Значения параметра char *, изменяющегося внутри функции - PullRequest
1 голос
/ 26 марта 2020

Я хочу создать программу, которая создает 2D-массив и заполняет его из stdin для последующей манипуляции. Первоначально я разработал его так, чтобы функция takeInput () принимала вводимые пользователем данные и возвращала символ * отдельной строки со всеми целыми числами, равными одному-ди git. Затем я намеревался получить этот символ * и передать его в качестве параметра во вторую функцию createArray () , которая соответственно заполнила бы массив.

Проблема возникает, когда значения моего параметра char * начинают изменяться (терять значения) внутри второй функции.

Примечание: Я выделил память для символа *, используя mallo c внутри первой функции с намерением, чтобы это не сделало его значения локальными для функции.

Моя главная выглядит так:

#include <stdio.h>
#include "functions.h"

int main(int argc, const char * argv[]) {

    const char *string = takeInput();
    int **initState = createArray(3, 3, string);

    return 0;
}

Это первая функция:

const char* takeInput() {
    char string2[10];
    /* some code */
    char *string0 = malloc(sizeof(string2));
    string0 = string2;
    return string0;
}

Это вторая функция:

int **createArray(int rows, int columns, const char *string) {
    int **array;
    int traverse = 0;
    // allocating memory for number of rows
    array = malloc(rows * sizeof(int*));

    // allocating memory for number of columns
    for(int i = 0 ; i < rows ; i++) {
        array[i] = malloc(columns * sizeof(int));
    }

    // populating indices in 2D array with values from string
    for(int i = 0 ; i < rows ; i++) {

        for(int j = 0 ; j < columns ; j++) {

            // converting chars to digits or the '_' char 
            if (string[traverse] != 95) {
                array[i][j] = (string[traverse] - 48);
            }

            else {
                array[i][j] = 48;
            }
            traverse++;
        }
    }
    return array;
}

Значения const char *string меняются, как только мой код достигает первого значения -l oop, и уменьшаются в размере во всей оставшейся части кода. Любые идеи / предложения с благодарностью!

Ответы [ 2 ]

2 голосов
/ 26 марта 2020

Вы возвращаете адрес локальной переменной, срок жизни которой закончится, как только функция вернется. Доступ к этому адресу впоследствии приводит к неопределенному поведению.

const char* takeInput() {
    char string2[10];
    char *string0 = malloc(sizeof(string2));
    string0 = string2;  // NOTE: string2 is not copied; string0 will just point to the address of string2 then
    return string0;     // here you actually return the address of string2
}

вместо этого используйте strcpy:

const char* takeInput() {
    char string2[10] = { 0 };
    // some code...
    char *string0 = malloc(sizeof(string2));
    strcpy(string0,string2);
    return string0;
}
2 голосов
/ 26 марта 2020

Программа имеет неопределенное поведение, потому что в этой функции

const char* takeInput() {
    char string2[10];
    /* some code */
    char *string0 = malloc(sizeof(string2));
    string0 = string2;
    return string0;
}

возвращается указатель на локальный массив

    string0 = string2;
    return string0;

. Кроме того, функция имеет утечку памяти, потому что выделена память и ее адрес назначен указателю string0, а затем указатель переназначен.

Если массив string2 содержит строку, то вы можете использовать стандарт C функция strcpy как

strcpy( string0, string2 );

В противном случае используйте функцию memcpy.

Обратите внимание, что в этом случае не рекомендуется использовать числа волхвов c, например 95 или 48 фрагмент кода

        // converting chars to digits or the '_' char 
        if (string[traverse] != 95) {
            array[i][j] = (string[traverse] - 48);
        }

        else {
            array[i][j] = 48;
        }

Кажется, вы имеете в виду следующее

        // converting chars to digits or the '_' char 
        if (string[traverse] != '_' ) {
            array[i][j] = (string[traverse] - '0');
        }

        else {
            array[i][j] = '0';
        }

, хотя, возможно, в выражении else вы имеете в виду 0 вместо '0'

        else {
            array[i][j] = 0;
        }
...