【问题标题】:Converting Static 2D Array to Dynamic Array in C在 C 中将静态二维数组转换为动态数组
【发布时间】:2021-01-02 19:39:53
【问题描述】:

我们被要求将二维静态数组转换为动态数组。所以我需要创建一个指针数组,其中每个指针都指向不同的行。我已经编写了这段代码,但是当 i=1 on line *(dynamicStr[i] + v) = rowStr[v]; 时我的代码会中断另外,如果我启用 free(ptr); 部分,我的调试器会卡在那里 6 或 7 次然后继续。

编辑:最后,我通过应用@dodooft 和@Viktor Terziev 给出的答案解决了这个问题。

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

void toDynamic(int x,int y, char toDyna[x][y]);

void toDynamic2(int x,int y, char toDyna[x][y]);

int main()
{
    char toDyna[7][12] = {
        "JOHN",
        "MARK",
        "PIERCEPIERCE",
        "20",
        "ROSIE",
        "ALEX",
        "MARLYN"
    };
    int x = 7;
    int y = 12;
    toDynamic2(x, y, toDyna);

    return 0;
}

void toDynamic2(int x,int y, char toDyna[x][y]){
    char *dynamicStr[x];
    int rowToCheck = 0;
    int size;
    char *ptr;
    int c;

    for(int i = 0; i < x; i++){
        printf("i: %d\n",i);
        c = 0;
        size = strlen(toDyna[rowToCheck]);
        ptr = (char*) malloc(size * sizeof(char));
        for(int j = 0; j < y; j++){
            if(toDyna[i][j] != '\0'){
                *(ptr+c) = toDyna[i][j];
                c++;
            } else{
                break;
            }
        }
        *(ptr+size) = '\0';
        printf(" ");
        char rowStr[size];
        for(int v = 0; v < size; v++){
            rowStr[v] = *(ptr+v);
            printf("Added Char: %c\n", rowStr[v]);
            *(dynamicStr[i] + v) = rowStr[v];
        }
        //free(ptr);
        //printf("\n%s\n", rowStr);
        //dynamicStr[i] = &rowStr;
        rowToCheck++;
    }
    for(int i = 0; i < x; i++){
        printf("%s\n", dynamicStr[i]);
    }
}

编辑:这是代码的工作版本:

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

char** toDynamic(int x,int y, char toDyna[x][y]);
void free2DArray(int x, char **dynamicStr);

int main()
{
    char toDyna[7][12] = {
        "JOHN",
        "MARK",
        "PIERCEPIERCE",
        "20",
        "ROSIE",
        "ALEX",
        "MARLYN"
    };
    int x = 7;
    int y = 12;
    char **dynamicArr;
    dynamicArr = toDynamic(x, y, toDyna);
    free2DArray(x, dynamicArr);
    return 0;
}

char** toDynamic(int x,int y, char toDyna[x][y]){
    printf("Q2\n");
    char **dynamicStr;
    int rowToCheck = 0;
    int size;
    int c;
    dynamicStr = (char*)malloc(x * sizeof(char*));
    for(int i = 0; i < x; i++){
        dynamicStr[i]  =  (char*)malloc(y * sizeof(char));
        c = 0;
        size = strlen(toDyna[rowToCheck]);
        char *ptr = (char*) malloc((size + 1) * sizeof(char));
        for(int j = 0; j < y; j++){
            if(toDyna[i][j] != '\0'){
                *(ptr+c) = toDyna[i][j];
                c++;
            } else{
                break;
            }
        }
        *(ptr+size) = '\0';
        dynamicStr[i] = ptr;
        rowToCheck++;
    }

    for(int i = 0; i < x; i++){
        printf("%s\n", dynamicStr[i]);
    }
    printf("----------------------------\n");
    return dynamicStr;
}

void free2DArray(int x, char **dynamicStr){
    printf("Q3\n");
    for(int i = 0; i < x; i++){
        free(dynamicStr[i]);
        printf("dynamicStr %d freed\n", i);
    }
    free(dynamicStr);
    printf("dynamicStr array freed\n");
    printf("----------------------------\n");
}

【问题讨论】:

  • 最长的字符串(12 个字符加上 NUL 终止符 = 13 个字符)对于静态数组来说太大了。
  • 将 char toDyna[7][12] 部分更改为 [7][13] 并将 y 更改为 13 但仍然发生同样的问题
  • 仅供参考,size = strlen(toDyna[rowToCheck]); ==> size = strlen(toDyna[rowToCheck]) + 1; - strlen 不包括终止符的空间。
  • @WhozCraig 当我打印尺寸时,我得到了正确的结果
  • @BurakSal 我不在乎,C 也不在乎。它可以让你毫不犹豫地轻松射中自己的脚。使用size,就像你拥有/拥有它(ptr+size) = '\0';` 调用*未定义的行为,这就是死亡(如果你幸运的话)。

标签: arrays c multidimensional-array


【解决方案1】:

您将dynamicStr 定义为一个字符指针数组,当您尝试使用*(dynamicStr[i] + v) = rowStr[v]; 为其分配值时,您基本上是将rowStr[v] 的值复制到dynamicStr[i] + v 指向的地址。该地址未在您的代码中定义,因此您遇到了段错误。

如果您尝试使用指向具有动态内存的新数组的指针填充dynamicStr,您应该尝试类似

dynamicStr[i] = ptr;

其中ptr 是malloc 调用返回的指向i-th 行的指针。此外,当您使用字符串时,您可以使用strcpy 将数据从静态数组复制到动态数组。

【讨论】:

    【解决方案2】:

    它比你想象的要容易得多,请参考strcpy documentationstrlen documentation,并且(如果你使用我的代码)不要忘记释放你的内存。

    char * * toDynamic2(size_t n, size_t m, char strings[n][m])
    {
        char * * arr = malloc(n * sizeof(char*));
    
        for(size_t i = 0; i < n; ++i)
        {
            size_t size = strlen(strings[i]);
            arr[i] = malloc((size + 1) * sizeof(char));
            strcpy(arr[i], strings[i]);
        }
    
        for(size_t i = 0; i < n; ++i)
        {
            printf("%s\n", arr[i]);
        }
    
        return arr;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-03
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-08
      相关资源
      最近更新 更多