1

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");
}
12
  • The longest string (12 characters plus NUL terminator = 13 characters) is too big for the static array. Commented Jan 2, 2021 at 19:43
  • changed the char toDyna[7][12] part to [7][13] and y to 13 but still same problem happens Commented Jan 2, 2021 at 19:44
  • 2
    Fyi, size = strlen(toDyna[rowToCheck]); ==> size = strlen(toDyna[rowToCheck]) + 1; - strlen doesn't include space for the terminator. Commented Jan 2, 2021 at 19:45
  • @WhozCraig when I print sizes I get the right results tho Commented Jan 2, 2021 at 19:46
  • 1
    @BurakSal I don't care, and neither does C. It lets you handily shoot yourself in the foot without a moment of hesitation. With size as you had/have it (ptr+size) = '\0';` invokes *undefined behavior, which is death (if you're lucky). Commented Jan 2, 2021 at 19:49

2 Answers 2

2

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;
}
Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.