(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_t
的 count
字节的内存,并使用 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]);
}
}
所以我试图获取大小为 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_t
的 count
字节的内存,并使用 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]);
}
}