Ошибка при возврате строки из функции - PullRequest
0 голосов
/ 05 декабря 2018

Это из задачи Codewars, поэтому я исключу ненужный код из этой функции.В основном, если n <= 1, мне нужно вернуть пустую строку.

char* sc(int n)
{
    if(n > 1) {
        //irrelevant code
    }

    //return strdup("");
    return "";
}

Если передаваемое значение равно -1, когда я использую return "";, я получаю сообщение "Тест не пройден", но когда яиспользуй return strdup(""); я сдаю тест.Просто интересно, почему это так?

Редактировать: так называется функция.Это только последний тест, который не пройден.

#include <criterion/criterion.h>
#include <string.h>

char* sc(int);

void dotest(int n, const char* expect)
{
  char* actual = sc(n);
  cr_expect(!strcmp(actual, expect), "Expected: '%s', got: '%s'\n", expect, actual);
  free(actual);
}

Test(the_multiply_function, should_pass_all_the_tests_provided) {
    dotest(2,"Aa~ Pa! Aa!");
    dotest(6, "Aa~ Aa~ Aa~ Aa~ Aa~ Pa! Aa!");
    dotest(7, "Aa~ Aa~ Aa~ Aa~ Aa~ Aa~ Pa!");
    dotest(10, "Aa~ Aa~ Aa~ Aa~ Aa~ Aa~ Aa~ Aa~ Aa~ Pa!");
    dotest(1, "");
    dotest(-1, "");
}

Ответы [ 3 ]

0 голосов
/ 05 декабря 2018

Функция sc () возвращает строковую константу "".Строковые константы автоматически выделяются в отдельной памяти.

sc () возвращает адрес этой строковой константы.В do test () вы сохраняете адрес в фактической переменной и освобождаете его.

Вы не должны освобождать эту память.Просто удалите free(actual);.

0 голосов
/ 05 декабря 2018

Для использования free(), из C11, глава §7.22.3.3 ( упор шахта )

Функция free создает пространство, на которое указываетptr подлежит освобождению, то есть предоставляется для дальнейшего распределения.Если ptr является нулевым указателем, никаких действий не происходит.В противном случае, , если аргумент не соответствует указателю, ранее возвращенному функцией управления памятью, или если пространство было освобождено при вызове free или realloc, , поведение не определено.

, а для strdup() ( снова выделено мое )

Функция strdup()возвращает указатель на новую строку, которая является дубликатом строки s. Память для новой строки получается с помощью malloc() и может быть освобождена с помощью free().

Так, когда вы используете return strdup("");, указатель, который возвращаетсяимеет право быть переданным в free() - все в порядке.

OTOH, говоря return "";, вы возвращаете указатель на первый элемент строкового литерала, который не является подходящим кандидатом дляпереданный в free(), как упомянуто выше, он вызывает неопределенное поведение .

Ошибка сбоя или сегментации одна из множества сторонаэффекты UB.

0 голосов
/ 05 декабря 2018

Задача, по-видимому, требует, чтобы функция возвращала динамически выделенную строку.Это видно из:

char* actual = sc(n);
...
free(actual);  // free is for dynamic allocated memory

Поэтому функция должна использовать функцию типа malloc для выделения строки.strdup делает это, то есть распределяет динамическую память и делает копию строки (т.е. "" в этом коде) в эту память.

Простое выполнение return ""; вернет адрес в строку (то есть "") со статической продолжительностью хранения, то есть некоторой памятью, которая не может быть освобождена.Вызов free в памяти со статической продолжительностью хранения приводит к неопределенному поведению, которое может привести к сбою программы.

...