我正在尝试使用2D数组进行动态内存分配,而我似乎无法使我的功能按预期工作。我想传递我的函数一长串字符,分解并将某些部分存储为单独的字符串(在他们自己的字符数组中),然后将它们添加到2D数组并返回最终的东西。将字符串拆分并存储我想要的函数的部分工作正常。内存分配是我做错了。
例如,我传递我的函数字符串“0 ,,,10000,10000,”奥尔巴尼高速公路之后的阿尔巴尼高速公路“,”“, - 32.1479054960,116.0201957650,4”并且它拉出'10000',' - 32.1479054960'和'116.0201957650',将它们存储在自己的数组中,然后将它们全部添加到一个名为'stop'的数组中。我(尝试)做的是为我将存储的3个字符串分配内存,然后当我添加字符串时,我为它们分配内存,因为它们被添加。
这是我的功能:
char **getStopData(char line[]) {
int commas = 0;
int len = strlen(line);
char **stop = malloc(3); //Block of memory for each string
char stop_id[20]; //Temp array to build stop_id string
char lat[20]; //Temp array to build lat string
char lon[20]; //Temp array to build lon string
int counter;
for(int i = 0; i <len; i++) {
if(line[i] == ',') {
commas++;
counter = 0;
continue;
}
switch(commas) { //Build strings here and store them - works fine
case 2 :
stop_id[counter++] = line[i];
if(line[i+1] == ',') stop_id[counter] = '\0';
break;
case 6 :
lat[counter++] = line[i];
if(line[i+1] == ',') lat[counter] = '\0';
break;
case 7 :
lon[counter++] = line[i];
if(line[i+1] == ',') lon[counter] = '\0';
break;
}
}
//Assign memory for each string to be added to 'stop' & add my strings to 'stop'
stop[0] = malloc(sizeof(stop_id));
stop[0] = stop_id;
stop[1] = malloc(sizeof(lat));
stop[1] = lat;
stop[2] = malloc(sizeof(lon));
stop[2] = lon;
return stop;
}
我的主要人物:
int main(int argc, char *argv[]) {
char **niceRows = getStopData(argv[1]);
for (int i=0; i<sizeof(niceRows); i++) {
printf("%d\n",*niceRows[i]);
free(niceRows[i]);
}
free(niceRows);
return 0;
}
当我运行我的函数时,我得到了一堆与我的内存分配有关的运行时错误。 error for object 0x7fff5266bb70: pointer being freed was not allocated set a breakpoint in malloc_error_break to debug
答案 0 :(得分:0)
此行返回指向已分配内存的指针
stop[ 0 ] = malloc( sizeof( stop_id ) );
下一行覆盖,并将指针更改为指向stop_id
stop[0] = stop_id;
对于停止[1]和停止[2]
相同你想做什么
memcpy( stop[ 0 ], stop_id, 20 );
编辑(通过M Oehm): 你也应该改变
char **stop = malloc(3);
到
char **stop = malloc( 3 * sizeof( char * ) );
答案 1 :(得分:0)
您的代码存在重大问题。
float **stop = malloc(3); //Block of memory for each string
仅分配3个字节或不的内存。你应该写:
float **stop = malloc(3 * sizeof(float *)); //Block of memory for each string
因为这会为3 float *
分配内存。
稍后,您stop[0] = malloc(sizeof(stop_id));
分配了20个字节的内存,但只能在其中写入 float
。你应该写得更好:
stop[0] = malloc(sizeof(float));
stop[1]
和stop[2]
相同。
最后你有for (int i=0; i<sizeof(niceRows); i++) {
niceRows
是float **
,即地址。它的大小在32位系统上是4,在64位上是8,但绝对不是你想要的。
应为for (int i=0; i<3; i++) {
但您在这里不需要float **
:float *
就足够了。
答案 2 :(得分:0)
您的分配应该是:
float **stop = malloc(3 * sizeof *stop);
malloc
获取sizeof
可以获得的字节数。这是C在低级函数中处理任意类型的方法,如memcpy
,memset
,fwrite
,qsort
和'malloc : You operate on byte memory with ´void *
指针。这会丢失类型信息,但允许您通过使用sizeof(T)
指定类型的大小(以字节为单位)来使用任何类型。
(这也容易出错,因为你必须保持数据和类型同步。)
在main中,您尝试使用sizeof
获取已分配的指针到浮点数组的长度:
for (int i = 0; i < sizeof(niceRows); i++) ...
这不起作用。 niceRows
的大小是指针的大小,可以是4或8,具体取决于您的系统。
无法知道为指针分配了多少内存。您必须将此信息保留为单独的值。您可以做的最好的事情是将指针分配给已分配的内存和结构中的大小信息。
在你的情况下,getStopData
总是返回一个包含float的三个指针的数组。这里不需要长度信息,但您应该记录返回的数组总是有三个条目的事实。所以:
for (int i = 0; i < 3; i++) ...
比数组更好的设计可能是一个结构,其中条目的名称已经告诉您正在查看的数据。
最后,您应该初始化临时字符缓冲区stop_id
,lat
和'隆起'以捕获少于7个逗号的情况。
答案 3 :(得分:-1)
使用指针到指针获取2D数组是无稽之谈,它是广泛传播但不正确,不好的做法。通过
获得指向动态2D阵列的指针{"responseProtocol":"PROTOCOL_JSON","requestProtocol":"PROTOCOL_JSON", "codes":"164"}
{"responseProtocol":"PROTOCOL_JSON","requestProtocol":"PROTOCOL_JSON", "codes":"122"}
{"responseProtocol":"PROTOCOL_JSON","requestProtocol":"PROTOCOL_JSON", "codes":"123"}
或者如果您的编译器是由恐龙设计的:
char (*ptr)[x][y] = malloc(char[x][y]);
其他所有内容都不会为您提供在相邻内存中分配的正确2D阵列。
在您的特定情况下,您可能甚至不想要2D数组,您需要一个指针数组,每个指针指向一个可变长度的字符串。这样的数组声明为char* ptr = malloc(sizeof(*ptr) * x * y);
。
在C中,您无法使用char* stop[3];
赋值运算符复制数组。你必须使用memcpy或strcpy。
您只能在静态分配的数组上使用=
运算符。