[英]Allocating memory dynamically to a 2-d array of strings
int ReadNames(char ***Names, int *r,int *c)
{
int i, j, k;
char name[100];
printf("Number of Rows: ");
scanf("%d", r);
printf("Number of Columns: ");
scanf("%d", c);
Names=(char ***)malloc(sizeof(char **)*(*r));
for(i=0;i<(*r);i++)
*(Names+i)=(char **)malloc(sizeof(char *)*(*c));
for(i=0;i<(*r);i++)
for(j=0;j<(*c);j++)
{
fflush(stdin);
gets(name);
strcpy(*(*(Names+i)+j),name);
}
return 1;
}
我正在嘗試將內存分配給字符串的二維數組。 稍后我想按行和列對它們進行排序,但是在分配內存時,程序沒有響應。 我在代碼中做些什么嗎?
在主函數中,readname稱為
ReadNames(&p,&r,&c)
其中r和c是編號。 行和列。
你需要:
*Names = (char **)malloc(sizeof(char **) * (*r));
以及隨之而來的變化。
您正在傳遞三指針,以便能夠返回雙指針。 您正在做的是丟失有關在哪里存儲雙指針的信息。
刪除的評論有些道理; 還有一個誤導。 2D字符串數組表示基本數據中具有三個級別的指針。 您需要將指針傳遞給函數的第四級。
同樣,使用gets()
是災難的秘訣。 永遠不要(像從不像從沒一樣, 永遠不要像以前一樣 )使用gets()
函數。 甚至在玩具程序中也沒有。 它會使您養成不良習慣。 第一個Internet蠕蟲通過使用gets()
的程序傳播(Google搜索“ morris Internet蠕蟲”)。
在Unix和其他基於POSIX的系統上,使用fflush(stdin)
會導致未定義的行為。 在Windows上,該行為由Microsoft定義。 如果您在Windows上運行,則可以。 如果不是,那么您不是。
而且我認為三星級編程很糟糕!
這可能不是我要做的方式,但這是將您編寫的內容直接轉換為可以正常工作的東西,以及一個main()
程序對其進行測試並釋放所有分配的內存。 假定strdup()
可用; 如果沒有,那么編寫它是微不足道的。
樣本輸出:
Number of Rows: 2 Number of Columns: 3 R0C0: Row 1, Column 1. R0C1: Ambidextrous Armless Individual. R0C2: Data for the third column of the first row. R1C0: Row 2, Column 1. R1C1: Row 2, Column 2. R1C2: Given that the number of rows is 2 and the number of columns is 3, this should be the last input! Rows = 2, cols = 3. [0,0] = <<Row 1, Column 1.>> [0,1] = <<Ambidextrous Armless Individual.>> [0,2] = <<Data for the third column of the first row.>> [1,0] = <<Row 2, Column 1.>> [1,1] = <<Row 2, Column 2.>> [1,2] = <<Given that the number of rows is 2 and the number of columns is 3, this should be the last input!>>
#include <stdio.h> #include <string.h> #include <stdlib.h> static void ReadNames(char ****Names, int *rows, int *cols) { char name[100]; printf("Number of Rows: "); scanf("%d", rows); printf("Number of Columns: "); scanf("%d", cols); int c; while ((c = getchar()) != EOF && c != '\\n') ; *Names = (char ***)malloc(sizeof(char ***)*(*rows)); for (int i = 0; i < (*rows); i++) (*Names)[i] = (char **)malloc(sizeof(char **)*(*cols)); for (int i = 0; i < (*rows); i++) { for (int j = 0; j < (*cols); j++) { printf("R%dC%d: ", i, j); if (fgets(name, sizeof(name), stdin) == 0) { fprintf(stderr, "Unexpected EOF\\n"); exit(1); } name[strlen(name)-1] = '\\0'; // Zap newline (*Names)[i][j] = strdup(name); } } } int main(void) { int rows; int cols; char ***data = 0; ReadNames(&data, &rows, &cols); printf("Rows = %d, cols = %d.\\n", rows, cols); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) printf("[%d,%d] = <<%s>>\\n", i, j, data[i][j]); } for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) free(data[i][j]); free(data[i]); } free(data); return 0; }
使用三個級別的指針已經足夠糟糕了。 四是恐怖。 此代碼將自身限制為三個級別的指針。 我假設具有C99兼容性,因此可以在函數中方便時聲明變量。 與C89 / C90編譯器一起使用的更改(現在已經逆行了14年)非常簡單。
#include <stdio.h> #include <stdlib.h> #include <string.h> static char ***ReadNames(int *r, int *c) { int i, j; char name[100]; printf("Number of Rows: "); scanf("%d", r); printf("Number of Columns: "); scanf("%d", c); int x; while ((x = getchar()) != EOF && x != '\\n') ; char ***Names = (char ***)malloc(sizeof(char ***)*(*r)); for (i = 0; i < (*r); i++) Names[i] = (char **)malloc(sizeof(char **)*(*c)); for (i = 0; i < (*r); i++) { for (j = 0; j < (*c); j++) { if (fgets(name, sizeof(name), stdin) == 0) { fprintf(stderr, "Unexpected EOF\\n"); exit(1); } name[strlen(name)-1] = '\\0'; Names[i][j] = strdup(name); } } return Names; } static void PrintNames(char ***Names, int r, int c) { int i, j; for (i = 0; i < r; i++) { for (j = 0; j < c; j++) printf("%s ", Names[i][j]); printf("\\n"); } } int main(void) { int rows; int cols; char ***data = ReadNames(&rows, &cols); PrintNames(data, rows, cols); printf("Rows = %d, cols = %d.\\n", rows, cols); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) printf("[%d,%d] = <<%s>>\\n", i, j, data[i][j]); } for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) free(data[i][j]); free(data[i]); } free(data); return 0; }
Number of Rows: 3 Number of Columns: 4 R1C1 R1C2 R1C3 R1C4-EOR R2C1 R2C2 R2C3 R2C4-EOR R3C1 R3C2 R3C3 R3C4-EOR R1C1 R1C2 R1C3 R1C4-EOR R2C1 R2C2 R2C3 R2C4-EOR R3C1 R3C2 R3C3 R3C4-EOR Rows = 3, cols = 4. [0,0] = <<R1C1>> [0,1] = <<R1C2>> [0,2] = <<R1C3>> [0,3] = <<R1C4-EOR>> [1,0] = <<R2C1>> [1,1] = <<R2C2>> [1,2] = <<R2C3>> [1,3] = <<R2C4-EOR>> [2,0] = <<R3C1>> [2,1] = <<R3C2>> [2,2] = <<R3C3>> [2,3] = <<R3C4-EOR>>
這兩個程序都在valgrind
下運行干凈。
所以,這是工作的代碼...
*Names=(char **)malloc(sizeof(char **)*(*r));
for(i=0;i<(*r);i++)
*(*Names+i)=(char*)malloc(sizeof(char *)*(*c));
for(i=0;i<(*r);i++)
for(j=0;j<(*c);j++)
{
fflush(stdin);
gets(name);
strcpy((*(*Names+i)+j),name);
}
但是在打印存儲的名稱時...我提供了一個功能。
int PrintNames(char **Names, int r, int c)
{
int i,j;
for(i=0;i<r;i++)
{ printf("\n");
for(j=0;j<c;j++)
printf("%s ",*(*(Names+i)+j));
}
return 1;
}
現在,此PrintNames也可以通過main ...作為“ PrintNames(p,r,c);”來調用。...但是程序在打印時停止了...可能是什么問題?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.