Как я могу передать динамический массив (malloced) в функцию? - PullRequest
1 голос
/ 15 января 2012

Мне нужно передать char * в функцию, но эта функция действительно нуждается в const?

Но я читаю это из файла, и оно для меня динамично:

fseek(fcode, 0, SEEK_END);
i=ftell(fcode);
square_scm = (char*) malloc(i);
//free(square_scm);
fseek(fcode, 0, SEEK_SET);
fread(square_scm, 1, i, fcode);
scheme_load_string(sc, square_scm);

Итак, square_scm:

"(display 
    (string-append "Answer: " 
    (number->string (square 6.480740698407859)) "\n"))юоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюоюо"

без бесплатного:

"(display 
    (string-append "Answer: " 
    (number->string (square 6.480740698407859)) "\n"))ННээээ««««««««««««««««ю"

Как мне сделать это как char [size], например:

"(display 
    (string-append "Answer: " 
    (number->string (square 6.480740698407859)) "\n"))"

Ответы [ 3 ]

4 голосов
/ 15 января 2012

Ваш free() - это катастрофа;вы только free() данные, когда вы закончили с ним.

Вероятно, вы должны быть ошибкой проверки кодов возврата, по крайней мере из malloc() и fread().

данныхчтение из файла не будет завершено нулем.Вам нужно перераспределить один байт и добавить NUL терминала ('\0') после считывания данных в выделенный буфер.(Обратите внимание, что файл мог сжаться с момента его открытия; обратите внимание на значение, возвращаемое с fread(). Если файл вырос, вы не увидите дополнительных данных, но никакого другого повреждения не произойдет.)

Вы спрашиваете о const.Предположительно функция square_cm() имеет подпись, такую ​​как:

void square_cm(SomeType *sc, const char *data_string);

, и вы беспокоитесь, что у вас есть char *, а не const char * в вашем коде вызова?

Выне нужно беспокоиться;компилятор добавит const для вас.const - это обещание вам, пользователю функции, что сама функция не будет изменять ваши данные.Он может принимать фиксированную строку (например, строковую константу) или динамически размещаемую строку, и это не имеет значения.Когда вы сталкиваетесь с проблемами, у вас есть const char * или строковый литерал, который вам нужно передать функции, которая принимает char *.Здесь функция само собой не обещает оставить строку в покое, что может вызвать проблемы.Например, вы не можете передать строковый литерал в strtok(), потому что функция пытается изменить строку, но строка, вероятно, находится в постоянной памяти, что вызывает проблемы (дампы ядра в Unix; повсеместно неопределенное поведение).

Итак, const в сигнатуре функции - это обещание потребителю (пользователю) функции ничего не менять.Вы можете передавать const или не- const данные в эту функцию, потому что они не будут изменены в любом случае.

2 голосов
/ 15 января 2012
  1. Вы используете освобожденный указатель, который вызывает неопределенное поведение.Вы должны удалить или переместить вызов free().
  2. Вы не можете завершать строку после того, как прочитали ее из файла.Вы должны завершить эту строку нулем.Что-то вроде:

    square_scm[i] = 0;
    

    Убедитесь, что вы выделили достаточно места для нулевого терминатора - это означает добавление +1 к вашему вызову malloc().

    Альтернативно, выможете добавить максимальную ширину поля к вашему вызову printf():

    printf("%*s", i, string);
    

    Хотя вы не указали код, где происходит печать, это может быть или не быть практичным.

Вероятно, вам следует также выполнить проверку ошибок.

1 голос
/ 15 января 2012

Не освобождайте испорченную память, пока не покончили с ней. И чтобы ответить на ваш вопрос, всегда оставляйте место для завершающего нулевого байта в строках и устанавливайте последний байт равным нулевому байту.

fseek(fcode, 0, SEEK_END);
i=ftell(fcode);

//allocate for null byte too
square_scm = malloc(i + 1);

//reset the memory before using it
memset(square_scm, 0, i + 1);

fseek(fcode, 0, SEEK_SET);
fread(square_scm, 1, i, fcode);
square_scm[i] = 0; //not really required as we have already memset it
scheme_load_string(sc, square_scm);

//now you should free it, assuming it is not used anymore
free(square_scm);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...