【问题标题】:Dynamic 3D Variable-column character Array Manipulation in CC中的动态3D可变列字符数组操作
【发布时间】:2016-02-28 08:41:05
【问题描述】:

我希望下面的代码生成一个类似于代码下面的结构。我没有从代码中得到它。

我希望代码创建一个 3D 动态数组,该数组包含如下所示的数据,这样当我想打印像 printf("%s\n",szData[2][3]); 这样的特定字符串时,我会得到 "string4"。另外,我想从特定位置获取特定字符,例如 putchar(szData[0][3][2] 我得到 'r'

尽管指定了位置,但下面的代码会打印出上次保存的数据。例如 printf("%s",szData[0][0]); 应该是 "string1" 它打印出 "string2" 这是 szData[2][1] 的数据。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char***szData;
    char temp[500];
    int i,j,k,x,n,m,index;

    printf("Rows:");
    scanf("%d",&n);

    szData=(char***)malloc(n*sizeof(char));

    for(i=0;i<n;i++){
        printf("Col: ");
        scanf("%d",&m);
        szData[i]=(char**)malloc(m*sizeof(char));
        for(j=0;j<m;j++){

            printf("string[%d][%d]=",i,j);
            scanf("%s",temp);
            szData[i][j]=(char*)malloc(25*sizeof(char));
            szData[i][j]=temp;

        }
    }


            printf("memmory[%d][%d]=%s\n",0,2,szData[0][2]);//Printing string from specific location


    return 0;
}

Expected structure:

     +----------+----------+----------+----------+
     |    0     |     1    |     2    |    3     |
+----+----------+----------+----------+----------+
| 0  |  string1 |  string2 | string3  |string4   |
+----+----------+----------+----------+--------- +
     +----------+----------+
     |    0     |     1    | 
+----+----------+----------+
| 0  |  string1 |  string2 | 
+----+----------+----------+
     +----------+
     |    0     |      
+----+----------+
| 1  |  string1 |  
+----+----------+
     +----------+----------+----------+----------+
     |    0     |     1    |     2    |    3     |
+----+----------+----------+----------+----------+
| 2  |  string1 |  string2 | string3  |string4   |
+----+----------+----------+----------+--------- +
     +----------+----------+
     |    0     |     1    |     
+----+----------+----------+
| 2  |  string1 |  string2 | 
+----+----------+----------+
     +----------+----------+----------+----------+
     |    0     |     1    |     2    |    3     |
+----+----------+----------+----------+----------+
| 2  |  string1 |  string2 | string3  |string4   |
+----+----------+----------+----------+--------- +
     +----------+----------+
     |    0     |     1    |     
+----+----------+----------+
| 2  |  string1 |  string2 | 
+----+----------+----------+

下面的代码可以正常工作。为什么不是上面的?

#include <stdio,h>
#include <stdlib.h>
#include <string.h>
int main()
{
    char***szData; 
    char temp[25];
    szData= (char *** )malloc(4 * sizeof(char ** )) ;
    szData[0]=(char**)malloc(2*sizeof(char));
    szData[0][0]=(char*)malloc(25*sizeof(char));
    szData[0][0]="Henry\0";
    szData[0][1]=(char*)malloc(25*sizeof(char));
    szData[0][1]="Korir\0";
    szData[1]=(char**)malloc(sizeof(char));
    szData[1][0]=(char*)malloc(25*sizeof(char));
    szData[1][0]="BSc.\0";
    szData[2]=(char**)malloc(3*sizeof(char));
    szData[2][0]=(char*)malloc(25*sizeof(char));
    szData[2][0]="Software Engineering\0";
    szData[2][1]=(char*)malloc(25*sizeof(char));
    szData[2][1]="Kenyatta\0 ";
    szData[2][2]=(char*)malloc(25*sizeof(char));
    szData[2][2]="University\0";
    szData[3]=(char**)malloc(sizeof(char));
    szData[3][0]=(char*)malloc(25*sizeof(char));
    szData[3][0]="From Kipsaiya, Kenya\0";

    printf("szData[%d][%d]=%c size=%d\n",0,1,szData[2][0][0],sizeof(szData[0][1]));
    strcpy(temp,szData[2][0]);
    putchar(szData[0][0][0]);
    printf("temp=%s size=%d\n",temp,sizeof(szData[2][0]));
return 0;
}

【问题讨论】:

  • Possible duplicate(免责声明:无耻插件)。
  • 你好。感谢您的贡献。代码在执行过程中崩溃。我希望看到您提供的代码有所改进。

标签: c arrays string pointers malloc


【解决方案1】:

这些分配是错误的

szData=(char***)malloc(n*sizeof(char));
                                ^^^^^ 
szData[i]=(char**)malloc(m*sizeof(char));
                                  ^^^^^

应该有

szData=(char***)malloc(n*sizeof(char **));
                                ^^^^^^^ 
szData[i]=(char**)malloc(m*sizeof(char *));
                                  ^^^^^^^

而不是赋值

szData[i][j]=temp;

导致内存泄漏你必须使用标准函数strcpy

strcpy( szData[i][j], temp );

此外,由于每行的列数是不同的,因此您应该以某种方式保留有关一行中的列数的信息。

一种方法是多分配一列并将最后一列设置为NULL

这是一个演示程序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main( void ) 
{
    char ***szData;
    unsigned int n, m;
    unsigned int i, j;

    printf( "Rows: " );
    scanf( "%u", &n );

    szData = ( char*** )malloc( n * sizeof( char ** ) );

    for ( i = 0; i < n; i++ )
    {
        printf( "Col: " );
        scanf( "%u", &m );

        szData[i] = ( char ** )calloc( ( m + 1 ), sizeof( char * ) );
        for ( j = 0; j < m; j++ )
        {
            char temp[25];
            printf( "string[%u][%u] = ", i, j );
            scanf( "%24s", temp );
            szData[i][j] = ( char * )malloc( strlen( temp ) + 1 );
            strcpy( szData[i][j], temp );
        }
    }

    printf( "\n" );

    for ( i = 0; i < n; i++ )
    {
        for ( j = 0; szData[i][j] != NULL; j++ ) printf( "%10s", szData[i][j] );
        printf( "\n" );
    }        

    for ( i = 0; i < n; i++ )
    {
        for ( j = 0; szData[i][j] != NULL; j++ ) free( szData[i][j] );;
        free( szData[i] );
    }

    free( szData );             

    return 0;
}

它的输出可能看起来像

Rows: 7
Col: 4
string[0][0] = string1
string[0][1] = string2
string[0][2] = string3
string[0][3] = string4
Col: 2
string[1][0] = string1
string[1][1] = string2
Col: 1
string[2][0] = string1
Col: 4
string[3][0] = string1
string[3][1] = string2
string[3][2] = string3
string[3][3] = string4
Col: 2
string[4][0] = string1
string[4][1] = string2
Col: 4
string[5][0] = string1
string[5][1] = string2
string[5][2] = string3
string[5][3] = string4
Col: 2
string[6][0] = string1
string[6][1] = string2

   string1   string2   string3   string4
   string1   string2
   string1
   string1   string2   string3   string4
   string1   string2
   string1   string2   string3   string4
   string1   string2

编辑:更新问题后,代码如下

szData[0][0]=(char*)malloc(25*sizeof(char));
szData[0][0]="Henry\0";

也是错的。

至少存在内存泄漏,因为首先szData[0][0] 被分配了已分配内存的地址,然后在下一条语句中被重新分配。

也没有必要写像"Henry\0"这样的字符串文字,因为字符串文字"Henry"已经有终止零。

【讨论】:

  • @K1b1w077 完全没有。我们初学者应该互相帮助。:)
  • 太棒了!现在我知道得更多了。
【解决方案2】:

szData[i][j]=(char*)malloc(25*sizeof(char)); 之后的szData[i][j]=temp; 导致内存泄漏。

分配足够的内存并复制读取的字符串。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char***szData;
    char temp[500];
    int i,j,k,x,n,m,index;

    printf("Rows:");
    scanf("%d",&n);

    szData=malloc(n*sizeof(char**));

    for(i=0;i<n;i++){
        printf("Col: ");
        scanf("%d",&m);
        szData[i]=malloc(m*sizeof(char*));
        for(j=0;j<m;j++){

            printf("string[%d][%d]=",i,j);
            scanf("%499s",temp);
            szData[i][j]=malloc((strlen(temp)+1)*sizeof(char));
            strcpy(szData[i][j],temp);

        }
    }


    printf("memmory[%d][%d]=%s\n",0,2,szData[0][2]);//Printing string from specific location

    return 0;
}

注意他们说的是you shouldn't cast the result of malloc() in C

【讨论】:

  • 你好。感谢您的贡献。代码在执行过程中崩溃。我希望看到您提供的代码有所改进。
  • 它没有在my test 中崩溃。你的意见是什么?
  • 我使用了随机字符串,比如名字。更重要的是,我必须对 malloc 进行类型转换才能在我的机器中编译。
猜你喜欢
  • 1970-01-01
  • 2020-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-25
  • 2019-03-31
  • 2020-07-31
相关资源
最近更新 更多