【发布时间】:2019-06-08 18:46:27
【问题描述】:
我在 C 中实现了一个 K-means 算法。它在大多数情况下运行良好,但使用 Valgrind 调试它告诉我我正在执行“8 大小的无效读取 - 8 大小的无效写入 - 无效在开头使用 '''memcpy''' 读取大小为 8"。我认为问题不存在,但是我为多维浮点数组元素分配了一个值,该内存是使用 '''malloc''' 动态分配的,并在某些时候使用 for 循环。因为 Valgrind 还告诉“地址 0x572c380 在分配大小为 80 的块后为 0 个字节”。
我尝试将分配的字节数加 1,因为我认为可能“需要”更多内存来完成其工作,但没有任何改变。我知道这可能是一个基本错误,但我对这门语言还是很陌生,而且在我的课程中,它并没有解释任何如此“技术性”的东西。我试图搜索错误的答案和解释,但我只发现了 '''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 会引发这些错误消息吗?
【问题讨论】:
-
请逐字逐句显示 valgrinds,并以文本形式完整显示。
-
memcpy调用确实没有做你显然认为它做的事情。它从源进行逐字节复制,这是一个 shallow 复制。 -
对不起,我已经编辑了:没有
righe变量,只有rows -
@Someprogrammerdude 你能解释一下
memcpy的正确用法吗,在这种情况下?我应该在m[i][j]中使用for 循环来memcpya[i][j]中的每个浮点数还是同样的问题?
标签: c pointers malloc valgrind