Burak Sal
Burak Sal

Reputation: 21

Converting Static 2D Array to Dynamic Array in C

We were asked to convert 2D static array to dynamic array. So I will need to create an array of pointers in which every pointer points to a different row. I have written this code but my code breaks when i=1 on line *(dynamicStr[i] + v) = rowStr[v]; Additionally, if I enable free(ptr); section my debugger gets stuck there for 6 or 7 times and then contiunes.

EDIT: In the end, I solved the problem with appying the answers @dodooft and @Viktor Terziev gave.

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

EDIT: This is the working verion of the code:

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

Upvotes: 1

Views: 340

Answers (2)

Viktor Terziev
Viktor Terziev

Reputation: 43

Its much easier than you think, please refer to strcpy documentation and strlen documentation, and (if you use my code) don't forget to free your memory.

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

Upvotes: 2

dodooft
dodooft

Reputation: 71

You define dynamicStr as an array of char pointers, when you are trying to assign a value to it with *(dynamicStr[i] + v) = rowStr[v]; you are basically copying the value of rowStr[v] to the address that is pointed by dynamicStr[i] + v. That address is not defined in your code, so you got a segfault.

If you are trying to fill dynamicStr with pointers to new arrays with dynamic memory, you should try something like

dynamicStr[i] = ptr;

where ptr is the pointer returned by the malloc call to the i-th row. Also, as you are working with strings you can use strcpy to copy the data from the static array to the dynamic one.

Upvotes: 1

Related Questions