2013-10-05 21 views
0

当我改变函数中我调用malloc的位置时,出现分段错误。 此代码正常工作并打印“结束\ n”。从哪里调用malloc从哪里来都没关系? - c

#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; 
} 

但是,这个看似等价的代码在分段错误的“点1 \ n”之前结束。

#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; 
} 

我在想什么? (我是一个初学者)

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

+0

首先阅读如何使用'malloc'! – haccks

+0

我读了其他东西,其中包括http://www.cplusplus.com/reference/cstdlib/malloc/的参考页面。对不起,这个愚蠢的错误,但我想我分配4个字节(我的系统中的一个int的大小),然后将指针指向该位置指向我的指针,然后检查它是否为null,以防万一。也许其他新手也有同样的困惑。 – niic

回答

5

在这两种方案,你在这里调用未定义行为:

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

pptr是被dereferenced存储由malloc返回的指针未初始化的指针。由于未定义的行为,第一个恰好看起来像它正在工作,但是正在破坏内存pptr正好指向。

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

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

2

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

当调用未定义的行为时,是的,订单可能很重要。任何事情都很重要。无论您的系统时间在程序运行开始时是偶数还是奇数都可以(但可能不会)重要。这就是未定义的手段。

在这种情况下,我怀疑这两个malloc会以某种方式通知编译器需要分配哪些内存,并且在第一种情况下,您碰巧覆盖到可写空间,因此“很幸运”。当然,在更大的计划中,你会感到不幸,因为我怀疑你失败了。

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