简体   繁体   English

C 数组在没有明显干预的情况下莫名其妙地改变了值

[英]C array inexplicably changes values without apparent intervention

I am writing some code to convert a matrix into a unique vector.我正在编写一些代码来将矩阵转换为唯一向量。 There are some conditions on the elements to be inserted in the vector, so I first run a test to determine what number of elements in each column that will go into the vector.对于要插入向量中的元素有一些条件,所以我首先运行一个测试,以确定将 go 插入向量中的每一列中的元素数量。 For that, I create a samples[] array with "number of columns" elements, and element k in this array represents the number of elements I will be transferring to the vector from column k.为此,我创建了一个包含“列数”元素的 samples[] 数组,该数组中的元素 k 表示我将从 k 列传输到向量的元素数。

The code is as follows:代码如下:

#include<stdio.h>
#include <stdlib.h>
#define INVISIBLE 999
    
void main()
{
    int i,j;
    int l=6, c=2;
    double testmat[6][2]={
    {3,9},
    {4,7},
    {2,5},
    {6,10},
    {2,6},
    {5,8}
    };
    
    printf("Our sample matrix\n");
    for(i=0;i<l;i++)
    {
        for(j=0;j<c;j++)
            printf("%.0f\t",testmat[i][j]);
        printf("\n");
    }
    
    
    unsigned long size=0;
    int samples[c];
    
    double vect[size];
    
    for(j=0;j<c;j++)
    {
        i=0;
        while((testmat[i][j]!=INVISIBLE) && (i!=l))
        {
            i++;
            size++;
        }
        samples[j]=i;
    }
    
    printf("Size = %d\n",size);
    printf("Samples:\n");
    for(j=0;j<c;j++)
        printf("samples[%d] = %d\t",j,samples[j]);
    printf("\n");
    
    int counter = 0;
    
    for(j=0;j<c;j++)
        for(i=0;i<6;i++) //Tried to put i<samples[j] but given the new value of samples[j] ...
        {
            printf("samples[%d]=%d\n",j,samples[j]);
            vect[counter]=testmat[i][j];
            counter++;
            // printf("(%d,%d)\t",i,j);
        }
}

I am quite lost as why the samples[] array changes by divine intervention... any help/explanation will be much appreciated我很迷茫,因为为什么 samples[] 数组会因上帝的干预而改变……任何帮助/解释都将不胜感激

Note these lines:请注意以下几行:

unsigned long size=0;
double vect[size];

You're using a variable length array (which is generally discouraged), but more importantly, you're saying that vect has a length of 0 ;您使用的是可变长度数组(通常不鼓励这样做),但更重要的是,您说vect的长度为0 it can't store anything.它不能存储任何东西。

This is a problem because later you do:这是一个问题,因为稍后您会这样做:

vect[counter]=testmat[i][j];

You're writing into an 0-length array.您正在写入一个长度为 0 的数组。 This will overwrite memory on the stack.这将覆盖堆栈上的 memory。 Apparently here, you end up overwriting data in samples .显然在这里,您最终会覆盖samples中的数据。 What will get overwritten though depends entirely on how the compiler chosen to place data on the stack, and how far off the end of the array you tried to access.什么会被覆盖完全取决于编译器如何选择将数据放在堆栈上,以及您尝试访问的数组末尾有多远。 It's undefined.它是未定义的。

If you're going to write into vect , it must have enough space to hold the data ahead of time.如果你要写入vect ,它必须有足够的空间来提前保存数据。


Apparently even declaring a 0-length array invokes undefined behavior, so it's difficult to say which part exactly is responsible here for your data being overwritten.显然,即使声明一个长度为 0 的数组也会调用未定义的行为,因此很难说这里究竟是哪一部分负责您的数据被覆盖。 Definitely don't write off the end of an array though.绝对不要注销数组的末尾。 Clobbering data on the stack won't lead to good times unless you like breaking things for malicious/educational purposes.除非您出于恶意/教育目的而破坏事物,否则破坏堆栈上的数据不会带来美好的时光。

You are writing beyond the size of an array, which is undefined behaviour.您正在写入超出数组的大小,这是未定义的行为。 One of such (undefined) behaviour could be that other memory areas are changed:此类(未定义)行为之一可能是其他 memory 区域已更改:

// this creates an array of size 0:
unsigned long size=0;
double vect[size];

...

// here you are writing to it:
vect[counter]=testmat[i][j];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM