繁体   English   中英

使用二维数组分配内存

[英]Allocating memory with 2D array

我正在尝试对二维数组使用动态内存分配,但似乎无法让我的函数按预期工作。 我想向我的函数传递一长串字符,将某些部分分解并存储为单独的字符串(在它们自己的字符数组中),然后将它们添加到二维数组并返回最终结果。 拆分字符串并存储我想要的内容的函数部分工作正常。 内存分配是我做错了。

例如,我将字符串 "0,,10000,10000,"Albany Hwy After Armadale Rd","",-32.1479054960,116.0201957650,4" 传递给我的函数,它会提取出 '10000', '-35.6001701717014.14' ',将它们存储在自己的数组中,然后将它们全部添加到一个名为 '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

这一行返回一个指向已分配内存的指针

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 * ) );

您的代码存在重大问题。

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 *就足够了。

你的分配应该是:

float **stop = malloc(3 * sizeof *stop);

malloc获取字节数,您可以通过sizeof获得。 这是 C 在低级函数(如memcpymemsetfwriteqsort和 ´malloc )中满足任意类型的方法: You operate on byte memory with ´void *: You operate on byte memory with ´void * 这会丢失类型信息,但允许您通过使用sizeof(T)以字节为单位指定类型的大小来使用任何类型。

(这也容易出错,因为您必须保持数据和类型同步。)

在 main 中,您尝试使用sizeof获取已分配的浮点指针数组的长度:

for (int i = 0; i < sizeof(niceRows); i++) ...

那行不通。 niceRows的大小是指针的大小,它是 4 或 8,具体取决于您的系统。

没有办法知道有多少内存分配给一个指针。 您必须将此信息作为单独的值保留。 您能做的最好的事情是将指向已分配内存的指针和结构中的大小信息捆绑在一起。

在您的情况下, getStopData始终返回一个包含三个浮点指针的数组。 此处不需要长度信息,但您可能应该记录返回的数组始终具有三个条目这一事实。 所以:

for (int i = 0; i < 3; i++) ...

比数组更好的设计可能是一种结构,其中条目的名称已经告诉您正在查看哪些数据。

最后,您可能应该初始化临时字符缓冲区stop_idlat和 'lon` 以捕获少于 7 个逗号的情况。

  • 使用指针到指针获取二维数组是无稽之谈,它被广泛传播但不正确,不好的做法。 一个指向动态二维数组的指针通过

    char (*ptr)[x][y] = malloc(char[x][y]);

    或者如果您的编译器是由恐龙设计的:

     char* ptr = malloc(sizeof(*ptr) * x * y);

    其他所有内容都不会为您提供在相邻内存中分配的正确 2D 数组。

  • 在您的特定情况下,您甚至可能不想要一个二维数组,您想要一个指针数组,每个指针指向一个可变长度的字符串。 这样的数组被声明为char* stop[3]; .

  • 在 C 中,不能使用=赋值运算符复制数组。 您必须使用 memcpy 或 strcpy。

  • 您只能在静态分配的数组上使用sizeof运算符。

暂无
暂无

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

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