从哪里调用malloc是否重要? - C

时间:2013-10-05 17:40:53

标签: c segmentation-fault malloc

当我改变函数中我调用malloc的位置时,我遇到了分段错误。 此代码工作正常并打印"结束\ n"。

#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 1\n");

    free(ptr);

    (*pptr)[0] = 1;

    free(*pptr);
    printf("End\n");
    return 0;
}

然而,这个看似相同的代码在&#34; Point 1 \ n&#34;之前结束。来自分段错误。

#include <stdio.h>
#include <stdlib.h>

int main() {    

    int *ptr;
    if (!( ptr = malloc(4) ))
        return 1;

    ptr[0]= 1;
    printf("Point 1\n");

    free(ptr);

    int **pptr;
    if (!( *pptr = malloc(4) ))
        return 1;
    (*pptr)[0] = 1;

    free(*pptr);
    printf("End\n");
    return 0;
}

我错过了什么? (我有点像初学者)

其他信息:我使用gcc在Ubuntu下使用Netbeans。

2 个答案:

答案 0 :(得分:5)

在这两个程序中,您在此处调用未定义的行为:

int **pptr;
if (!( *pptr = malloc(4) ))
    return 1;

pptr是一个未初始化的指针,被取消引用以存储malloc返回的指针。由于未定义的行为,第一个似乎恰好看起来有效,但是在pptr碰巧指向的地方正在破坏内存。

第二个失败,因为pptr碰巧指向无法写入的内存区域。

此外,由于在上面的代码中正在分配int*malloc(4)是不安全的。使用malloc(sizeof(int*))。例如,64位系统通常具有8字节指针。

答案 1 :(得分:2)

什么是sizeof(int)?如果是> 4然后是的,你正在调用未定义的行为。

当调用未定义的行为时,是的,顺序可能很重要。一切都很重要。在程序运行开始时系统时间是偶数还是奇数可以(但可能不会)。这就是未定义的含义。

在这种情况下,我怀疑两个mallocs以某种方式通知你的编译器要分配的内存,并且你在第一种情况下“幸运”,因为它恰好覆盖了可写空间。当然,在较大的计划中,你运气不好,因为我怀疑你是默默无闻的。

无论如何,首先让程序正确,然后找出你的UB是什么,然后找出可能导致它的实现细节。