Двумерное расположение строк с помощью указателей в C - PullRequest
0 голосов
/ 23 января 2020

Я хочу создать двумерный массив строк с использованием указателей, поскольку, выполнив это, я позже смогу освободить динамическую c память и создать меньший или больший массив, используя тот же идентификатор (переменную).

Я использовал код:

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

unsigned long rows = 0;
unsigned long cols = 0;
unsigned long chrs = 30;

char ***mtx = NULL;

int rszmtx(char ***, unsigned long, unsigned long);

int main(int argc, char *argv[]) {
    rszmtx(mtx, 0, 0);

    for (int r = 0; r < rows; r++) {
        for (int c = 0; c < cols; c++) {
            strcpy(mtx[r][c], "[]");
        }
    }

    for (int r = 0; r < rows; r++) {
        for (int c = 0; c < cols; c++) {
            printf("%s ", mtx[r][c]);
        }
        printf("\n");
    }

    return 0;
}

int rszmtx(char ***matrix, unsigned long y, unsigned long x) {
    if (y <= 0) {
        printf("Enter the number of rows: ");
        scanf("%lu", &rows);
    } else {
        y = rows;
    }

    if (x <= 0) {
        printf("Enter the number of cols: ");
        scanf("%lu", &cols);
    } else {
        x = cols;
    }

    free(matrix);
    matrix = (char ***) malloc(rows * sizeof(char **));

    if (matrix == NULL)
        return 1;

    for (int r = 0; r < rows; r++) {
        matrix[r] = (char **) malloc(cols * sizeof(char *));

        for (int c = 0; c < cols; c++) {
            matrix[r][c] = (char *) malloc (chrs * sizeof(char));
        }
    }

    return 0;
}

В функции "main" я хочу вызвать функцию "rszmtx" и назначить размер для "mtx", заданного пользователем. Затем я хочу, чтобы все строки были "[]", и распечатать их. Проблема в том, что я ничего не могу ни назначить, ни напечатать. При тестировании я заметил, что если я помещаю отображение и / или печать в функцию «rszmtx», все работает нормально. Почему это так, как я могу отобразить и распечатать "mtx" вне функции "rszmtx"?

Ответы [ 2 ]

0 голосов
/ 23 января 2020

Если это строковая матрица, я бы не делал это, как ваше решение с ********* указателями, только создавал бы набор функций, подобный этому:

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

#include <stdio.h>

#define SFUNC 1

typedef struct
{
    int malloced;
    char *string;
}STRING_t;

typedef struct
{
    size_t xsize;
    size_t ysize;
    STRING_t strings[];
}STR2D_t;


STR2D_t *init(size_t xsize, size_t ysize)
{
    STR2D_t *str2D = calloc(sizeof(str2D) + xsize * ysize * sizeof(str2D -> strings[0]), 1);
    str2D -> xsize = xsize;
    str2D -> ysize = ysize;
    return str2D;
}

char *setstr2D(STR2D_t *str2D, const char *str, size_t xpos, size_t ypos)
{
    char *result = NULL;
    #if SFUNC
    if(str2D && str2D -> xsize > xpos && str2D -> ysize > ypos)
    #endif
    {
        STRING_t *strStruct = &str2D -> strings[xpos + ypos * str2D -> ysize];
        #if SFUNC
        if(strStruct -> malloced)
        {
            free(strStruct -> string);
            strStruct -> malloced = 0;
        }
        #endif
        strStruct ->  string = (char *)str;
        result = (char *)str;
    }
    return result;
}

char *strcpy2D(STR2D_t *str2D, const char *str, size_t xpos, size_t ypos)
{
    char *result = NULL;
    #if SFUNC
    if(str2D && str2D -> xsize > xpos && str2D -> ysize > ypos)
    #endif
    {
        STRING_t *strStruct = &str2D -> strings[xpos + ypos * str2D -> ysize];
        if(strStruct -> string) strcpy(strStruct -> string, str);
        result = strStruct -> string;
    }
    return result;
}

char *strmalloc2D(STR2D_t *str2D, size_t size, size_t xpos, size_t ypos)
{
    char *result = NULL;
    #if SFUNC
    if(str2D && str2D -> xsize > xpos && str2D -> ysize > ypos)
    #endif
    {
        STRING_t *strStruct = &str2D -> strings[xpos + ypos * str2D -> ysize];
        result = realloc(strStruct -> malloced ? strStruct -> string : NULL, size);
        if(result) 
        {
            strStruct -> string = result;
            strStruct -> malloced = 1;
        }
    }
    return result;
}


char *strdup2D(STR2D_t *str2D, const char *str, size_t xpos, size_t ypos)
{
    char *result = strmalloc2D(str2D, strlen(str) + 1, xpos, ypos);
    if(result) result = strcpy2D(str2D, str, xpos, ypos);
    return result;
}

0 голосов
/ 23 января 2020

Вы должны передать указатель по ссылке. Например,

int rszmtx(char ****mtx, unsigned long y, unsigned long x);

//…

rszmtx(&mtx, 0, 0);

В противном случае функция работает с копией оригинального указателя mtx, и изменение копии в функции не влияет на оригинал; указатель.

И нет смысла определять указатель глобально.

...