(C) malloc 使用随机数破坏了最大大小

(C) malloc corrupted top size with random numbers

所以我试图获取大小为 count 的随机 8 位数字数组,但每当计数大于 6 时,我都会收到损坏的顶部大小错误。我读到它应该与内存分配有关,但我无法弄清楚到底出了什么问题。我是 C 的新手,所以我不确定指针是否写对了。

int *randBytes(int count) {

    srand(time(0));
    int *num = calloc(count, sizeof(uint8_t));

    for (int i = 0; i < count; i++) {
        num[i] = (rand() % 255) + 1;
    }

    return num;
};

int main() {
    int randLen = 120;
    int *nums = randBytes(randLen);
    for (int i = 0; i < randLen; i++) {
        printf("%d ", nums[i]);
    }
}

应该是int *num = calloc(count, sizeof(int));

int *num = calloc(count, sizeof(uint8_t));

您正在分配大小为 count * 1 == count 的缓冲区。如果 sizeof(int) == 4 那么数组可以包含 count / 4 个整数。

for (int i = 0; i < count; i++) {
    num[i] = (rand() % 255) + 1;
}

然后您将该数组视为 count 个整数的数组,而不是 count / 4 个整数。


您可以通过更改 calloc:

来解决此问题
int *num = calloc(count, sizeof(*num));

或您的 for 循环:

for (int i = 0; i < count / sizeof(int); i++) {
    num[i] = (rand() % 255) + 1;
}

int *num = calloc(count, sizeof(uint8_t));

从上面的行开始,通过执行 calloc,您正在创建类型为 uint8_tcount 字节的内存,并使用 int* 来存储和访问动态创建的内存.

这恰好是你得到损坏数据的原因,当你取消引用它以初始化数组中的每个元素时,你一次取消引用 4 个字节(32 位),因为指针是输入 int 而不是 uint8_t 会根据您的要求取消引用 1 个字节(8 位)。假设您的数组计数是 10 ,您确实创建了一个 10 字节的数组,但是执行初始化的 for 循环最终访问了 40 个字节,导致数据损坏,并且可能最终由于无效的内存访问(由于访问内存)而导致分段错误那超出了您创建的 10 个字节的范围)。

您可以对代码进行以下更改以使其正常工作

uint8_t* randBytes(int count) {

    srand(time(0));
    uint8_t *num = calloc(count, sizeof(uint8_t));

    for (int i = 0; i < count; i++) {
        num[i] = (rand() % 255) + 1;
    }

    return num;
};

int main() {
    int randLen = 120;
    uint8_t *nums = randBytes(randLen);
    for (int i = 0; i < randLen; i++) {
        printf("%d ", nums[i]);
    }
}