简体   繁体   English

动态地将内存分配给字符串的二维数组

[英]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;
}

I am trying to allocate the memory to a 2-D array of strings. 我正在尝试将内存分配给字符串的二维数组。 Later on i want to sort them row wise and column wise, but while allocating the memory , the program is not responding. 稍后我想按行和列对它们进行排序,但是在分配内存时,程序没有响应。 Is there something i am doing in my code. 我在代码中做些什么吗?

in main function readname is called as 在主函数中,readname称为

    ReadNames(&p,&r,&c)

where r and c are the no. 其中r和c是编号。 of rows and columns. 行和列。

You need: 你需要:

 *Names = (char **)malloc(sizeof(char **) * (*r)); 

and consequential changes. 以及随之而来的变化。

You're passing a triple-pointer in order to be able to return a double-pointer. 您正在传递三指针,以便能够返回双指针。 What you're doing is losing the information about where to store the double-pointer. 您正在做的是丢失有关在哪里存储双指针的信息。

There is some truth to the struck out comment; 删除的评论有些道理; there is also a miscue. 还有一个误导。 A 2D array of strings means that you have three levels of pointer in the basic data. 2D字符串数组表示基本数据中具有三个级别的指针。 And you need a fourth level of pointer to pass into the function. 您需要将指针传递给函数的第四级。

Also, using gets() is a recipe for disaster. 同样,使用gets()是灾难的秘诀。 Don't ever (as in never , as in never ever ) use the the gets() function. 永远不要(像不像从没一样, 永远不要像以前一样 )使用gets()函数。 Not even in toy programs. 甚至在玩具程序中也没有。 It gets you into bad habits. 它会使您养成不良习惯。 The first Internet worm propagated through a program that used gets() (Google search 'morris internet worm'). 第一个Internet蠕虫通过使用gets()的程序传播(Google搜索“ morris Internet蠕虫”)。

On Unix and other POSIX-based systems, using fflush(stdin) leads to undefined behaviour. 在Unix和其他基于POSIX的系统上,使用fflush(stdin)会导致未定义的行为。 On Windows, the behaviour is defined by Microsoft. 在Windows上,该行为由Microsoft定义。 If you're running on Windows, then you're OK; 如果您在Windows上运行,则可以。 if not, you're not. 如果不是,那么您不是。


And I thought Three-Star Programming was bad! 而且我认为三星级编程很糟糕!

This probably isn't the way I'd do it, but it is a pretty direct translation of what you wrote into something that works, along with a main() program that tests it and frees all the allocated memory. 这可能不是我要做的方式,但这是将您编写的内容直接转换为可以正常工作的东西,以及一个main()程序对其进行测试并释放所有分配的内存。 It assumes strdup() is available; 假定strdup()可用; if not, it is trivial to write it. 如果没有,那么编写它是微不足道的。

Sample output: 样本输出:

 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!>> 

Working 4-star code: 工作的四星级代码:

 #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; } 

Alternative 3-star code 备用三星级代码

Using three levels of pointer is bad enough; 使用三个级别的指针已经足够糟糕了。 four is horrid. 四是恐怖。 This code restricts itself to three levels of pointer. 此代码将自身限制为三个级别的指针。 I assume C99 compatibility, so variables can be declared when convenient in a function. 我假设具有C99兼容性,因此可以在函数中方便时声明变量。 The changes to work with C89/C90 compilers (which are 14 years retrograde now) are simple enough. 与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; } 

Example output 输出示例

 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>> 

Both programs run clean under valgrind . 这两个程序都在valgrind下运行干净。

So, this is the code working... 所以,这是工作的代码...

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

but while printing those names stored...i have a function provided.. 但是在打印存储的名称时...我提供了一个功能。

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;

}

Now this PrintNames is also called through main...as "PrintNames(p, r, c);"....but program stops while printing...What could be wrong? 现在,此PrintNames也可以通过main ...作为“ PrintNames(p,r,c);”来调用。...但是程序在打印时停止了...可能是什么问题?

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

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