【问题标题】:int i in for loop not changing the address (c language)int i in for循环不改变地址(c语言)
【发布时间】:2013-11-17 04:01:11
【问题描述】:

所以我试图动态生成一个随机整数数组。问题是相同的地址 j 被添加到数组中。有人可以对此有所启发吗?感谢您的宝贵时间。

#define size 100

int main(void){
    srand(time(NULL));

    int *array = (int *) malloc(sizeof(int) * size);

    for (int i = 0; i < size; i += 1){
        int j = rand();
        array[i] = &j;
    }

    IntArray_printArray(array, size);
}

打印函数的输出:

Array Contents: [2702], [2702], [2702], [2702], [2702], [2702],  ... [2702], [2702], [2702], [2702], [2702], [2702],  ... [2702], [2702], [2702], [2702], [2702], [2702]

编辑 1:“IntArray_printArray”函数:

void IntArray_printArray(int *array, int size){
    printf("Array Contents: ");
    if (size <= 20){
        printf("Array Contents: ");
        for (int i = 0; i < size - 1; i += 1){
            printf("[%d], ", *(int*)array[i]);
        }
        printf("[%d]\n", *(int*)array[size-1]);
    } else {
        for (int i = 0; i < 6; i += 1){
            printf("[%d], ", *(int*)array[i]);
        }
        printf(" ... ");
        for (int i = size/2 - 3; i < size/2 + 3; i += 1){
            printf("[%d], ", *(int*)array[i]);
        }
        printf(" ... ");
        for (int i = size - 6; i < size - 1; i += 1){
            printf("[%d], ", *(int*)array[i]);
        }
        printf("[%d]\n", *(int*)array[size-1]);
    }
}

【问题讨论】:

  • 似乎函数 IntArray_printArray 是罪魁祸首。把这个函数的代码贴出来,方便大家判断问题。
  • 编译器应该给你一个关于这个代码的警告,因为array[i]是一个int,但是你正试图给它分配一个int*。如果您没有在启用警告的情况下进行编译,请这样做。如果是,请不要忽略警告。
  • @Buddha Thx,我添加了功能
  • size 的值是多少?你初始化了吗?否则malloc 可能会失败,然后分配给array[i] 时会出现分段错误,因为如果malloc 失败,array == NULL
  • 是的,它是顶部的#define。我会添加它

标签: c arrays dynamic int


【解决方案1】:

j的地址是未指定的,但不是随机的。虽然从技术上讲,它不必在每次循环迭代中位于相同的地址,但如果你遇到一个没有将它放在相同地址的编译器,我会感到惊讶。

要记住的另一件事是,一旦循环完成,j 的生命周期就结束了。因此,存储在array 元素中的任何地址的生命周期都结束了。不再引用这些指针是无效的。

所以IntArray_printArray() 打印出的值甚至可能不反映您存储在j 变量中的任何随机值(我假设IntArray_printArray() 打印出数组中指针指向的值,而不是指针本身的值)。

【讨论】:

  • 这实际上是一个相当深刻的答案,值得仔细阅读。
【解决方案2】:

j 的地址不会改变,因为 C++ 编译器优化了变量j 的创建并为其分配了一个固定地址(基本上在堆栈上)。

以下是汇编语言级别(伪 asm)可能发生的情况:

2702 
2698 <- stack_ptr pointing here(32 bit machine)

;new instruction to create `j`
addl stack_ptr, $4 ;j created

2702 <- stack_ptr pointing here now
2698

for 块结束后,堆栈指针减 4

2702
2698 <- stack_ptr here, after loop block ends, but not that `for` loop itself has ended.

然后循环重复。

【讨论】:

    【解决方案3】:

    就用这个吧:

    数组[i] = j;

    否则,您将存储随机数的固定地址。

    编辑:以上对我来说很好,添加了一些测试代码供 Chris 检查:

    #include <stdio.h>
    #include <stdlib.h>
    int main() {
    
        srand(time(NULL));
    
        const int size = 10;
    
        int *array = (int *) malloc(sizeof(int) * size);
    
        for (int i = 0; i < size; i++){
            int j = rand();
            array[i] = j;
            printf("array[%d] = %d \n", i, array[i]);
        }
    
        return 0;
    }
    

    【讨论】:

    • 这会导致程序崩溃。
    • 程序如何崩溃?它崩溃的线路是什么?错误是什么?
    • 我不知道。我正在使用 Eclipse;它只是说“program.exe 已停止工作。Windows 正在检查问题的解决方案......”
    • 嗨,克里斯,它对我有用,一定是您的程序中导致问题的其他原因。请参阅上面的编辑,我添加了一些测试代码供您检查,这对我来说运行良好。
    【解决方案4】:

    我认为即使 j 的生命周期地址只是在循环中,但它在堆栈中是相同的地址,就像 Aniket 说的那样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-11
      • 1970-01-01
      相关资源
      最近更新 更多