Инициализация строки пустой строкой

Мне было интересно, можно ли инициализировать строку пустой строкой следующим образом:

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

char* some_function() {
    char* w = malloc(100*sizeof(char));
    w = "";
    if (1 == 2) {
        w = "Not empty anymore";
    }
    return w;
}

int main(void) {

    char* word = some_function();
    int r = strcmp("", word);

    printf("%s\n", word);
    printf("%d\n", r);
    return 0;
}

Он отлично компилируется и дает мне желаемый результат, однако я все еще новичок в C и мне было интересно, не приведет ли это к каким-либо проблемам в будущем. Кроме того, мое использование strcmp для сравнения слова с "" в порядке?


person PCR    schedule 07.04.2016    source источник
comment
Что представляет собой if (1 == 2) в коде?   -  person GShaik    schedule 07.04.2016
comment
Я просто вставил это, чтобы оператор if был ложным и не выполнялся, поэтому возвращаемая строка была пустой строкой. В основном мне интересно, можно ли инициализировать такую ​​пустую строку и возвращать ее в функцию. На самом деле оператор if может быть истинным, а может и нет, в результате чего функция возвращает пустую строку или строку, которая больше не пуста.   -  person PCR    schedule 07.04.2016
comment
Это не рекомендуется делать, вместо этого, выполняя инициализацию, как указано выше, вы можете использовать функцию strcpy().   -  person GShaik    schedule 07.04.2016
comment
1) Вместо назначения с помощью = используйте strcpy. 2) Включите stdlib.h (для malloc и free) 3) free выделенную память из main.   -  person Spikatrix    schedule 07.04.2016


Ответы (2)


Ну, это вроде как возможно, но оно не будет вести себя так, как вы ожидаете. А в более поздних версиях C это неопределенное поведение.

Что вы сделали, так это выделили память, а затем выбросили этот указатель, таким образом, утечка этой памяти. Вы заменили указатель неконстантным указателем на строковый литерал (который должен заставить ваш компилятор выдать предупреждение или ошибку).

Это сработало в вашем случае. К счастью, вы не пытались писать в эту память. Если вы это сделали, есть вероятность, что произойдет что-то плохое.

person paddy    schedule 07.04.2016
comment
что должно заставить ваш компилятор выдать предупреждение или ошибку -- в C const не требуется. Не будет никакого предупреждения. (Я знаю, что const настоятельно рекомендуется при указании на строковый литерал). - person Spikatrix; 07.04.2016

О, о! Вы выделяете память для строки и сохраняете дескриптор выделенной памяти в w:

char* w = malloc(100*sizeof(char));

В следующей строке вы перезаписываете этот дескриптор неизменяемым строковым литералом:

w = "";

Это означает, что (1) вы больше не можете освобождать w после его использования, как должны, и (2) что w теперь указывает на строку в постоянной памяти, изменение которой приведет к неопределенному поведению, скорее всего, к сбою.

Динамически выделяемая память ведет себя как массив. Строки C — это массивы символов, которые содержат допустимые символы строки до завершающего нулевого символа '\0'. Поэтому установка первого символа на нулевой символ даст вам пустую строку:

*w = '\0';

or

w[0] = '\0';

В мертвой ветке вы хотите заполнить массив символов содержимым строки, но также назначаете литерал только для чтения. Вы можете использовать функцию strcpy из <string.h> для заполнения массива символов строкой:

strcpy(w, "Not empty anymore");

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

person M Oehm    schedule 07.04.2016
comment
Ах я вижу. Но можно ли использовать strcmp(, word)? - person PCR; 07.04.2016
comment
Да. Для strcmp не имеет значения, доступна строка только для чтения или нет, потому что strcmp только проверяет строку. Когда вы создаете свои собственные строки посимвольно, убедитесь, что строка имеет в конце нулевой терминатор '\0'. И когда вы выделяете память для строки, убедитесь, что есть место для дополнительного нулевого символа. В вашем случае строка может содержать 99 символов плюс нулевой символ. - person M Oehm; 07.04.2016