2

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

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] = &i,我就不需要malloc. 我一直认为这两件事本质上是同一件事,但肯定有一些我不明白的关键区别来保证malloc与一个一起使用。

我真的很困惑为什么我malloc真的需要在这里。我对内存分配相当陌生,我真的不明白什么时候应该使用它(显然)并且想知道是否有人可以为我解决这个问题。

4

5 回答 5

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)). 您正在为 a 分配空间int,而不是为 a分配空间int *

于 2013-04-02T18:33:29.397 回答
1

是的,我认为这很难理解,因为我在 for 中间被重新定义了。我马上重写代码。我写了 i 而不是 index 和 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。当您不知道需要多少数据时,您需要动态内存。编写此代码,以便您的其余代码仍然可以工作,但没有 malloc。

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

下面的代码意味着,array[index] 应该指向存储 i 的内存地址。它不会复制 i 中的值,所以当你更改 i,或者 i 被删除时,这将导致这个指针是故障,并在以后引起问题。你不应该这样做。

arr[index] = &i
于 2013-04-02T18:45:14.317 回答
1

这样写:

*arr[index] = i;

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

arr[index] = &i;

意思是:复制到的i地址arr[index]

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

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

于 2013-04-02T18:46:15.697 回答
0

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

你没有i在这里展示如何声明。但是,在大多数情况下,它是一个局部变量,或者可能是传递给方法的参数。在任何一种情况下,该变量的空间都在堆栈上声明。您可以使用 获取该变量的地址&i,但该变量将在方法结束后消失并且代码将这些值从堆栈中弹出。您可能会很幸运,并且只要您需要,该价值就不会受到影响。但是当另一个方法被调用时,该值很可能被覆盖并繁荣,你的程序充其量只能表现不正确。

i如果在全局范围内声明,您可以逃脱惩罚。

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

于 2013-04-02T18:38:39.483 回答
0

一个关键的区别是,一旦超出范围,它&i就会不复存在(或者,更确切地说,那块内存可以被重用于其他东西......它可能不会包含你认为它包含的东西)。i

于 2013-04-02T18:34:08.880 回答