当我更改调用 malloc 的函数中的位置时,我遇到了分段错误。此代码工作正常并打印"End"。
#include <stdio.h>
#include <stdlib.h>
int main() {
int **pptr;
if (!( *pptr = malloc(4) ))
return 1;
int *ptr;
if (!( ptr = malloc(4) ))
return 1;
ptr[0]= 1;
printf("Point 1n");
free(ptr);
(*pptr)[0] = 1;
free(*pptr);
printf("Endn");
return 0;
}
但是,这个看似等效的代码在分段错误的"点 1"之前结束。
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
if (!( ptr = malloc(4) ))
return 1;
ptr[0]= 1;
printf("Point 1n");
free(ptr);
int **pptr;
if (!( *pptr = malloc(4) ))
return 1;
(*pptr)[0] = 1;
free(*pptr);
printf("Endn");
return 0;
}
我错过了什么?(我有点初学者)
其他信息:我在 Ubuntu 下使用 Netbeans,使用 gcc。
在这两个程序中,您都在此处调用未定义的行为:
int **pptr;
if (!( *pptr = malloc(4) ))
return 1;
pptr
是一个未初始化的指针,正在取消引用以存储 malloc
返回的指针。 由于未定义的行为,第一个恰好看起来像它正在工作,但在pptr
碰巧指向的地方破坏了内存。
第二个失败,因为pptr
恰好指向无法写入的内存区域。
此外,由于在上面的代码中分配了int*
,因此malloc(4)
不安全。 使用 malloc(sizeof(int*))
. 例如,64 位系统通常具有 8 字节指针。
什么是sizeof(int)
? 如果是> 4,那么是的,您正在调用未定义的行为。
当调用未定义的行为时,是的,顺序可能很重要。任何事情都很重要。在程序运行开始时,您的系统时间是偶数还是奇数可能(但可能不会)重要。这就是未定义的含义。
在这种情况下,我怀疑这两个 malloc 以某种方式通知您的编译器要分配什么内存,并且在第一种情况下您"很幸运",因为它恰好覆盖了可写空间。当然,在更大的计划中,你倒霉了,因为我怀疑你默默地失败了。
无论如何,首先使程序正确,然后弄清楚你的UB是什么,然后找出可能导致它的实现细节。