调用printf更改由地址C传递的数组

时间:2017-09-22 04:34:14

标签: c arrays printf

我有一堆代码,它通过地址(指针)获取一个数组 这个函数只需要一个数组和一个整数值,这是它的长度,并逐个打印出数组的元素。

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。

这到底是怎么回事?!

这没有任何意义。我在内存中传递了数组的地址,所以我不希望堆栈与此有任何关系?

2 个答案:

答案 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。

普罗斯特!