C中的内存分配和指针

时间:2013-04-02 18:31:03

标签: c pointers malloc

我正在学习考试,我遇到了一些我很难理解的东西。我们正在使用指针和内存分配,而我只是在弄乱事物,试图看看改变了什么。我有这段代码:

int * arr[10];
for(i=0; i<5;i++) 
{
    int index = i;
    arr[index] = malloc(sizeof(int*));
    int i = 2 * index;
    *arr[index] = i;
    printf("arr [%d] = %d\n", index, *arr[index]);  /* should be 0, 2, 4, 6, 8 */
}

但我发现如果不使用* arr [index] = i,我使用arr [index] =&amp; i我不需要malloc。我一直认为这两件事本质上是一回事,但必须有一些我不理解的关键区别,以保证使用malloc

我真的很困惑为什么我真的需要malloc。我对内存分配相当新,我真的不明白什么时候它应该被使用(显然),并且想知道是否有人可以为我清除这一点。

5 个答案:

答案 0 :(得分:4)

请尝试使用此代码:

int * arr[10];
for(i=0; i<5;i++) 
{
    int index = i;
    int value = 2*i;
    arr[index] = malloc(sizeof(int*));
    *arr[index] = value;
}

for (i=0; i<5; i++)
{
    int index = i;
    printf("arr [%d] = %d\n", index, *arr[index]);  /* should be 0, 2, 4, 6, 8 */
}

如果你进行了改变,你现在就会有未定义的行为。鉴于此代码仍然有效。

你有未定义的行为,因为*arr[0]现在指向一个已经留下范围的堆栈内存。


你的malloc实际应该是malloc(sizeof(int))。您要为int分配空间,而不是为int *分配空间。

答案 1 :(得分:1)

是的,我认为很难理解,因为我在for的中间重新定义了。我现在会改写代码。我写了i而不是索引和2 * i而不是重新定义的i。

int * arr[10];
for(i=0; i<5;i++) 
{
    arr[i] = malloc(sizeof(int));
    *arr[i] = 2*i;
    printf("arr [%d] = %d\n", i, *arr[i]);  /* should be 0, 2, 4, 6, 8 */
}

这里你不需要动态内存,你知道将使用数组0-4。当您不知道需要多少mutch数据时,您需要动态内存。编写此代码,以便其余代码仍然有效,但没有malloc。

int array[5];
int **arr=array;

以下代码表示,数组[index]应指向我存储的内存地址。它不会复制i中的值,因此当您更改i或我被删除时,这将导致此指针有问题,以后会引起问题。你不应该这样做。

arr[index] = &i

答案 2 :(得分:1)

这样写道:

*arr[index] = i;

表示:将i的值复制到arr[index]指向的内存位置(在代码中先前分配)。

arr[index] = &i;

表示:将i的地址复制到arr[index]

在您的代码中i会在for循环中自动创建,并且只存在于该循环中。一旦离开循环(范围),用于存储i的内存就可以自由地分配给任何新创建的变量。

正如sharth建议的那样,尝试查看原始for循环之外的值,以查看一些有趣的结果。

答案 3 :(得分:0)

一个关键的区别是&i一旦i超出范围就会停止存在(或者说,那段内存可以重复用于其他东西......这可能不会包含您认为包含的内容。)

答案 4 :(得分:0)

编辑:我在下面说你没有说明i是如何宣布的。实际上,如果在循环中使用i,则重新声明它,隐藏原始值。无论如何,i将在循环结束时超出范围,或者可能在例程结束时超出范围。

您不会在此处显示i的声明方式。但是,在大多数情况下,它是局部变量或传递给方法的参数。在任何一种情况下,该变量的空间都在堆栈上声明。您可以使用&i获取该变量的地址,但该方法结束后该变量将消失,并且代码会将这些值从堆栈中弹出。你可能会很幸运,只要你需要,你就可以保持这个价值不变。但是,当另一种方法被调用时,该值可能会被覆盖并繁荣,您的程序最多会出现错误行为。

如果全局声明i,你可以侥幸成功。

此外,即使在更改i的值后,您也指向相同的地址。如果在例行程序结束时打印出数组的所有值,您会发现它们都是相同的值 - 您放入数组的最后一个值。那是因为数组中的每个条目都指向同一个位置。