我有一堆代码,它通过地址(指针)获取一个数组 这个函数只需要一个数组和一个整数值,这是它的长度,并逐个打印出数组的元素。
void dumpInts(int *array, int count, int hex){
int i;
for(i = 0; i < count; i++){
printf(" %*d",10,array[i]);
}
以上代码高度简化,以下是代码的其余部分。它不是那么大。
#include <stdio.h>
#include <stdlib.h>
int LAST = -1059786739;
int FIRST = -559038737;
//Input is a series of integers read in from stdin separated by whitespace
void dumpInts(int *array, int count, int hex);
void initArray(int *array, int size);
int main(){
int bufsiz ;
if(scanf("%d",&bufsiz) < 1){
fprintf(stderr,"CAN\'T READ BUFSIZ\n");
return 1;
}
if(bufsiz < 1){
fprintf(stderr,"BAD BUFSIZ=%d\n",bufsiz);
return 1;
}
bufsiz+=2;
int *array = (int *)malloc((size_t)bufsiz);
if(array == NULL){
fprintf(stderr,"NO MORE MEM\n");
return 1;
}
array[0] = FIRST;
array[bufsiz-1] = LAST;
initArray(array,bufsiz);
dumpInts(array,bufsiz,0);
dumpInts(array,bufsiz,1);
return 0;
}
void initArray(int *array, int size){
int i;
for(i = 1; i < size - 1; i++){
array[i] = i;
}
}
void dumpInts(int *array, int count, int hex){
int i;
for(i = 0; i < count; i++){
printf(" %*d",10,array[i]);
}
这就是事情。当数组的大小小于7时,它的效果很好。看看我的终端上的这个片段:
-559038737 1 2 3 4 -1059786739
突然间,当大小超过7时,最后一个元素被覆盖并且以下所有内存都被设置为随机值,但是第7个元素总是被设置为相同的东西...... {{1 }}
下面是一个大小为8的数组
1041
现在在我进一步发展之前,我觉得我应该发挥作用,我确实花了很多时间小心地缩小阵列被破坏的地方。在进入函数之前,它就是我所期望的,只要第一个循环打印出来,阵列就会被破坏。
好的,这就是它变得奇怪的地方。我通过SSH连接到我大学的linux机器,并运行了我的代码。没有clobber,阵列就好了。
以下比较尺寸7
我的: -559038737 1 2 3 4 5 1041 0 892677408 942878777
大学:
-559038737 1 2 3 4 5 1041
我即将重启我的机器....
*刚刚重新启动,同样的问题仍然存在......同样的数字......相同的大小...
另外,当我在大学计算机上编译代码并将其复制到我的机器上时,阵列仍然被破坏了。当我在我的机器上编译它时不是这样。
我的机器和大学机器都是基于unix的系统,运行linux。
这到底是怎么回事?!
这没有任何意义。我在内存中传递了数组的地址,所以我不希望堆栈与此有任何关系?
答案 0 :(得分:1)
您的问题中隐含的诊断调用printf更改通过地址传递的数组是不正确的:您没有按地址传递数组,而只是按值传递数组元素而printf
确实不要改变阵列。你观察到的是未定义行为的影响。
元素数量和分配数组的大小之间存在一些混淆:您可以使用更有意义的名称来表示数组元素的数量(count
),而不是数组的大小以字节为单位,传递给malloc()
。
编码后,您没有为数组分配足够的内存,初始化此数组的代码和打印它的代码都有未定义的行为,因为您访问超出其边界的数组。
此外,您不使用hex
参数在十进制和十六进制输出之间进行选择。
以下是更正后的版本:
#include <stdio.h>
#include <stdlib.h>
int LAST = -1059786739;
int FIRST = -559038737;
//Input is a series of integers read in from stdin separated by whitespace
void dumpInts(const int *array, int count, int hex);
void initArray(int *array, int size, int start);
int main(void) {
int count;
if (scanf("%d", &count) != 1) {
fprintf(stderr,"Cannot read the number of elements\n");
return 1;
}
if (count < 1) {
fprintf(stderr,"Invalid count=%d\n", count);
return 1;
}
count += 2;
int *array = malloc(sizeof(*array), count);
if (array == NULL) {
fprintf(stderr,"Out of memory\n");
return 1;
}
array[0] = FIRST;
initArray(array + 1, count - 2, 1);
array[count - 1] = LAST;
dumpInts(array, count, 0);
dumpInts(array, count, 1);
return 0;
}
void initArray(int *array, int count, int start) {
for (int i = 0; i < count; i++) {
array[i] = start + i;
}
}
void dumpInts(count int *array, int count, int hex) {
for (int i = 0; i < count; i++) {
if (hex) {
printf(" %10x", array[i]);
} else {
printf(" %10d", array[i]);
}
}
}
答案 1 :(得分:0)
int *array = (int *)malloc((size_t)bufsiz);
应该是:
int *array = (int *)malloc((sizeof(int))*bufsiz);
完整的解释:
void *malloc(size_t size);
是malloc的原型。如你所知,size_t是长无符号整数。
但是类型转换不问题。
让我说输入bufsize = 8;
然后:int *array = (int *)malloc((size_t)bufsiz);
变为int *array = (int *)malloc(10);
实际应该是int *array = (int *)malloc(4*10);
因为我们要存储10个整数&amp;考虑到sizeof(int)= 4。
因此指针指向10个字节而不是40个字节。因此没有足够的内存来存储整数。
这是一个 ArrayIndexOutOfBoundsException ,其中不存在。
C 不进行绑定检查,即它永远不会出现此错误。 因此,如果你继续递增指针,它只是简单地进入malloc的缓冲区(需要读/写操作),并且代码不会发生段错误,直到它耗尽了系统分配给程序的内存。
也你没有释放记忆; free(array)缺失。
编辑:malloc不接受对象计数。它需要分配的字节数。您正在使用malloc作为calloc。
普罗斯特!