C++中的结构是否按顺序分配内存?每次都以某种方式获得指针比较的正确答案
Are Structs in C++ allocated memory sequentially? Somehow getting correct answer for pointer comparison everytime
我正在尝试解决一个问题。
问题定义:给定一个包含 n 个节点的单链表。修改前半节点的值,使第一个节点的新值等于最后一个节点的值减去第一个节点的当前值,第二个节点的新值等于倒数第二个节点的值减去第二个节点的当前值,前半部分节点也是如此。如果 n 为奇数,则中间节点的值保持不变。请注意,链表的半节点保持不变。
EG : 6 3 5 4 10
答: -4 -1 5 4 10
我编写了一个程序来跟踪下半部分的节点,其顺序与使用递归处理所需的顺序相反。但是,出于粗心大意,我比较了两个指针,以检查两个指针是否相互交叉以停止处理它们。
我每次都正确获得输出。
完整代码:
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int data;
struct Node* next;
};
struct Node* modifyTheList(struct Node *head);
void push(struct Node **head_ref, int new_data)
{
struct Node* new_node =(struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = *head_ref;
*head_ref = new_node;
}
void printList(struct Node *head)
{
if (!head)
return;
while (head->next != NULL)
{
cout << head->data << " ";
head = head->next;
}
cout << head->data << endl;
}
int main()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
struct Node *head = NULL;
while(n--){
int a;
cin>>a;
push(&head, a);
}
head = modifyTheList(head);
printList(head);
}
return 0;
}
void modify(Node *head ,Node** left)
{
if(head!=NULL)
{
modify(head->next,left);
if(head >= *left ) //line of concern, comparing pointers
return;
else
{
(*left)->data=(*left)->data-head->data;
(*left)=(*left)->next;
}
}
}
struct Node* modifyTheList(struct Node *head)
{
if(head==NULL || head->next==NULL )
return head;
struct Node *temp = head;
modify(head,&temp);
return head;
}
有人可以告诉我这样比较有效吗?
如果这不成立,它是如何通过在线评委的测试用例的?
有人可以告诉我这样比较有效吗?
不能直接比较指针,除非它们指向同一数组的子对象或同一对象的成员。从形式上讲,不属于同一数组的对象被视为单独的1 元素数组的一部分。比较它们的指针没有定义的结果。引用 N4296:
§5.9 关系运算符 [expr.rel] ְְ¶3
比较对象86的指针定义如下:
(3.1( — 如果两个指针指向同一数组的不同元素,或者 其子对象,指向具有较高元素的指针 下标比较更大。
(3.2( — 如果一个指针指向 元素,或其子对象,以及另一个指针 将一个指向数组的最后一个元素,即后一个指针 比较更大。
(3.3( — 如果两个指针指向不同的 同一对象的非静态数据成员,或此类对象的子对象 成员,递归地指向后来声明的成员的指针 如果两个成员具有相同的访问控制,则比较更大 (第11条(,前提是他们的班级不是工会。
86(为此目的,不是数组元素的对象被视为属于单元素数组;参见5.3.1。
所以你不能直接比较,你的程序正式具有未定义的行为。但是,这种比较可能很有用,这就是为什么该标准为您提供了另一种方法:
§20.9.6 比较 [比较] ְְ¶14
对于更大、更少、greater_equal和less_equal的模板,任何指针类型的专用化 生成总订单,即使内置运算符 <、>、<=、>= 不生成
。
因此,只需将head >= *left
替换为调用std::greater_equal<Node*>(head, *left)
即可很好地定义您的代码。
如果这不成立,它是如何通过在线评委的测试用例的?
未定义的行为意味着语言规范允许任何结果。"工作"是一种可能的结果。你不能指望它总是结果。
不,绝对不能保证不同分配的内存的关系位置。
如果这不成立,它是如何通过在线评委的测试用例的?
(来自我(的简单答案是说你(不(幸运。事实是,内存分配/映射的机制很复杂,涵盖了更多的层:应用程序(malloc
(,C库实现,操作系统和硬件。连续的malloc
请求可能会返回一些连续的内存,在某些情况下甚至有可能。这绝不是保证,很容易中断(例如,在一系列交织在一起的malloc
和free
之后(。
此外,如@StoryTeller所示,将指针(相等性除外(与不同对象进行比较是 UB。
- 用于基于成员字段或函数创建比较器的快捷方式
- 内置用于比较两个(或多个)值的方式
- 重载 == 以递归方式比较两个链表
- STL映射比较器能否以某种方式获取指向映射本身的指针?
- C++中的结构是否按顺序分配内存?每次都以某种方式获得指针比较的正确答案
- ARM NEON aarch64:如何以优化的方式比较和更新 neon 寄存器
- 为什么这个简短的比较没有优化我预期的方式?
- 在 C++11 中编译时以词典方式比较两个字符串
- 消除有符号和无符号整数表达式之间比较的优雅方式
- 以最有效的方式比较两个向量
- C++等于(==)重载,比较所有属性的快捷方式或最佳方法
- 以格式化的方式打开一个具有日期的文件,并获取该日期进行比较
- 比较sha1哈希是否相等的最佳方式
- 二进制比较操作的优雅方式
- 比较输入值和从文件中读取值的最佳方式
- 比较数组的最佳方式
- C++ 字符串比较运算符>根据两个字符串的比较方式生成不同的输出
- 对象列表,按键(其成员之一)排序的最快方式(复杂度比较)
- 以本地化安全的方式比较C++中的字符串/字符和字符串/字符文本
- 最准确和正确的方式来比较两个大的windows 8.1注册表文件(c++ / c#或任何其他)