c-动态分配多维浮点数组的正确方法是什么? Valgrind错误

时间:2019-01-14 18:36:26

标签: c pointers malloc valgrind

我正在C语言中实现K-means算法。大多数情况下,它运行良好,但是用Valgrind对其进行调试时告诉我,我正在执行“大小8的无效读取-大小8的无效写入-无效开头使用'''memcpy'''读取大小8“。我认为问题并不存在,但是我在其中为多维浮点数组元素分配了一个值,该内存在某个时候通过for循环通过'''malloc'''动态分配。 “因为Valgrind还告诉“地址0x572c380是在分配了大小为80的块之后为0字节”。

我试图在分配的字节数上加1,因为我认为也许'''malloc'''“需要”更多的内存来完成其工作,但是什么都没有改变。我知道这可能是一个基本错误,但是我对这门语言还是很陌生,在我的课程中,它并没有解释任何“技术性”的内容。我试图搜索错误的答案和解释,但是我只发现了'''char'''数组的问题,而那些我理解的函数'''strcpy'''可以解决问题。浮点数组呢?这是第一次使用'''memcpy'''。

以下是引发这些Valgrind消息的代码段。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void main(){
    FILE* fp; //used to open a .txt file to read
    char buf[100];
    float ** a;
    char * s;
    int i;
    int j;
    int rows = 10;
    fp = fopen("data.txt", "r");
    if(fp==NULL){
        perror("Error at open file.");
        exit(1);
    }

    a = (float**) malloc(rows*sizeof(float*));
    for(i=0; i<rows; i++){
        s = fgets(buf, 100, fp); //reading .txt file
        if (s==NULL){
            break;
        }
        a[i] = malloc(dim*sizeof(float));
        a[i][0] = atof(strtok(s, ","));
        for(j=1; j<dim; j++){
            a[i][j] = atof(strtok(NULL,","));  //save as float value the                token read from a line in file, for example, from line "1.0,2.0,3.0" as first line -> get a[0][1] = 2.0
        }
    }
    fclose(fp);

    m = (float**) malloc(rows*sizeof(float*));
    for (i=0; i<rows; i++){
        m[i]=malloc(dim*sizeof(float)); //not initialized
    }

    memcpy(m, a, rows*dim*sizeof(float));
}

有人还能帮我理解为什么会起作用,但是Valgrind会提出这些错误消息吗?

1 个答案:

答案 0 :(得分:0)

您首先要分配一个float*数组,然后 分配几个float数组,因此您的最后一个memcpy(m, a, rows*dim*sizeof(float))复制了一个{{1} }(指向float*的指针)到另一个,但使用float浮点数,@ SomeProgrammerDude正确地指出了这一点。那会复制指针,而不是

此外,正如@xing指出的那样,您正在分配rows * dim,但使用rows(未显示)。可能是引起问题的原因。

我建议在第一行上一次分配整个数组,然后让所有其他行指向适当的行:

righe

(当然要添加a = malloc(rows * sizeof(float*)); a[0] = malloc(dim * rows * sizeof(float)); // Allocate the whole matrix on row #0 for (i = 1; i < rows; i++) { a[i] = a[0] + i * dim; // sizeof(float) automatically taken into account as float* pointer arithmetics } ... m = malloc(rows * sizeof(float*)); m[0] = malloc(dim * rows * sizeof(float)); memcpy(m[0], a[0], dim * rows * sizeof(float)); 条支票)