[英]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 在低級函數(如memcpy
、 memset
、 fwrite
、 qsort
和 ´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_id
、 lat
和 '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.