为什么在将新元素分配给char指针时似乎不需要“realloc”?

时间:2010-09-21 23:17:44

标签: c arrays pointers

我正在尝试创建一个指向char指针的指针,我可以轻松地添加新元素(字符串)。当我想添加新项目时,我使用 malloc 创建前2个维度和 realloc 。我使用和不使用 realloc 编写代码,我得到了相同的结果。这是预期的/正常的行为吗?


使用realloc

    char **p; // create pointer to char pointer
    p = malloc(sizeof(char*) * 2); // allocate 2 dimensions
    p[0] = "ab";
    p[1] = "cd";

    void* resizedP = (void*)realloc(p, sizeof(char*) * 4); // resize array
    p = (char**)resizedP;
    p[2] = "ef";
    p[3] = "gh";

    printf("%s \n", p[0]); // prints ab
    printf("%s \n", p[1]); // prints cd
    printf("%s \n", p[2]); // prints ef
    printf("%s \n", p[3]); // prints gh

    free(p);


没有realloc

    char **p;
    p = malloc(sizeof(char*) * 2);

    p[0] = "ab";
    p[1] = "cd";
    p[2] = "ef";
    p[3] = "gh";

    printf("%s \n", p[0]); // prints ab
    printf("%s \n", p[1]); // prints cd
    printf("%s \n", p[2]); // prints ef
    printf("%s \n", p[3]); // prints gh

    free(p);

5 个答案:

答案 0 :(得分:8)

绝对有必要调用realloc()来调整malloc()获得的内存块的大小。您通过访问已分配给程序的内存块的边界来调用未定义的行为

在您分配的内存块之后可能会有一些重要数据,您的第二个代码段将会运行。如果程序甚至因为越界错误而尝试访问另一个进程中的内存块,操作系统会大声抱怨(导致分段错误)。

无法保证您的第二个代码段(没有realloc())将来不会崩溃或以其他方式失败。这次碰巧工作了。

答案 1 :(得分:4)

在你的情况下,它可能巧合。例如,您的C库的malloc()可能会决定将您的分配大小填充为恰好为>= 2*sizeof(void*)的某个数字。

但是,理论上,没有什么可以阻止后续malloc返回恰好位于p[2]的字节。也没有什么可以阻止malloc返回一个值,在你请求的大小之后,操作系统没有将任何页面映射到地址空间。因此,您不应该依赖此行为。如果没有分配合适的金额,请不要写入p[2],因为这可能导致以下任何一种情况:

  • 您覆盖其他一些函数已编写的值。
  • 其他一些功能可能会在以后覆盖您。
  • 您可能会在尝试访问它时崩溃。

答案 2 :(得分:3)

尝试通过 valgrind 或使用 -fstack-protector 编译器开关运行第二个选项。您可能会获得有关为什么In silico的答案是正确的更多信息。

答案 3 :(得分:2)

假设您的p是一辆可容纳20人的公共汽车。

你试图把30个人放进去(没有放大)。有时它会起作用,如果它们不胖的话 ......

关于C未定义的行为。任何事情都可能发生。你刚才不走运,它“有效”。

简而言之:不要那样做!

答案 4 :(得分:1)

哇,不要那个男人!这是有道理的,它只不过是麻烦。

首先,p不是一个数组,它是一个指针,您可以通过检查sizeof(p)来看到它,它将始终返回4或8,具体取决于您运行的是32位还是64位系统。 / p>

指针指向内存中的位置,因此如果您尝试打印指针,您将获得一个内存地址,例如32位计算机上的0x0B32D2F1,当您调用其中一个*alloc函数时,处理器找到您请求的大小的空闲内存块,并将其分配给您的程序。

你所做的是访问和编辑尚未分配给你的内存,虽然很容易,没有什么能阻止你这样做,但这很糟糕,因为内存可能被分配给不同的程序,然后是用户当你崩溃他的其他程序时会恨你。简而言之,总是会分配您将使用的记忆! ALWAYSS!

哦,是的,那么处理器可能会将您正在使用的未分配内存分配给另一个程序,这将使您的程序混乱。