LINUX.ORG.RU

Лишние символы в конце строки - C

 , , ,


0

1

Я выполняю операции декодирования, записываю всё это в массив длиной 5000, и конвертирую его в понятный для программы формат. В большистве случаев строка отображается нормально, но в некоторых выдаёт такое: «SourceX\x06». В норме выдаёт «Source».

Это мой код:

char string[5000] = {‘S’,‘o’,‘u’,‘r’,‘c’,‘e’,‘\0’};

char *out = malloc(strlen(string) + 1);

strcpy(out, string);

return out;

Помогите, я не знаю в чём дело, пробовал уменьшать длину массива до 6, убирал при этом +1, но не помогло, в конце опять этот бред.

Очевидно, что ты накосячил с индексами и длинами, и что приведенный код к проблеме не относится. Мог просто написать «у меня проблемы», с тем же эффектом.

anonymous ()
Ответ на: комментарий от anonymous

Где здесь проблема? Если я возвращаю просто «Source» вместо конвертирования, таких символов в конце нет. Это вообще образец из интернета, сам я так и не додумался, как в этом мегасложном C работать с текстом. Вообще отвратительный язык, хуже java в 100 раз.

gradle ()

По-моему кусок выделенный malloc'ом не зануляется, может быть дело в этом.

Если у тебя такие проблемы с си уже на этом этапе, то пиши лучше на js или пистоне. Это не троллинг.

crutch_master ★★★★★ ()
Последнее исправление: crutch_master (всего исправлений: 1)

В приведённом примере ошибок не вижу. Но если ты используешь strncpy, 0 в конце может не поставиться если под него не хватит места и будет мусор.

mittorn ★★★★★ ()
Ответ на: комментарий от gradle

Ну, массив, который out я и имею ввиду.

Еще strcpy свой сделай. Или сделай дамп всех переменных циферками и посмотри что там внутри.

crutch_master ★★★★★ ()
Последнее исправление: crutch_master (всего исправлений: 2)
Ответ на: комментарий от crutch_master

В цикле пробегись по массиву да занули, как вариант.

почему не memset?

сделай дамп всех переменных циферками и посмотри что там внутри.

но ведь есть отладчик

SR_team ★★★★ ()
Ответ на: комментарий от SR_team

почему не memset?

Я думаю после предложения занулить первый аргумент strcpy, про memset можно и не говорить. Да и компилятор скорее всего сам memset этот и вставит.

Deleted ()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от gradle

Вообще отвратительный язык, хуже java в 100 раз.

Звучит примерно как «КАМАЗ отвратительная машина, хуже Матиза в 100 раз». Он просто немного для другого, и работа со строками там действительно боль. Но не стоит своё неосиляторство переносить на язык.

Если есть возможность, посмотри на C++. Он почти так же эффективен, как C, но строки там человеческие.

Если нет — разбирайся с длинами и выделяемой памятью. Я вот вижу у тебя return out, значит, это всё же не самостоятельная программа, а функция, которая вызывается откуда-то извне. И возвращаемый результат, видимо, char*, я угадал?

Судя по коду, проблемы где-то таки за его пределами (строку эту ты где-то, наверное, выводишь?) Память освобождается тоже где-то ещё. Возможно, освобождается до того, как ты выводишь строку. В общем, не видя полного кода, гадать и не угадывать можно бесконечно.

hobbit ★★★★★ ()

Длину массива до 6 уменьшать нельзя, надо 7, один байт под завершающий ноль. +1 тоже убирать нельзя. Лучшая альтернатива malloc+strcpy функция strdup, но она нестандартная посмотри, может она у тебя есть?

char string[5000] = {‘S’,‘o’,‘u’,‘r’,‘c’,‘e’,‘\0’};
return strdup(string);
dyb4hzvo ()
Последнее исправление: dyb4hzvo (всего исправлений: 1)
Ответ на: комментарий от crutch_master

А, ну да. Ну и что такого?

strcpy это не strcat, ему не нужна нульнотерминаторная строка в первом аргументе. Только во втором. Так что без разницы что там malloc вернул в массиве.

В честь чего?

Потому что может. gcc -S проверяй сам.

Deleted ()
Ответ на: комментарий от Deleted

Потому что может. gcc -S проверяй сам.

Ну у меня и без -S везде нули, но не факт, что у него также. Я думаю там его iconv может цепляться за /0+/wtf и получать хз что, причём рандомно. Вообще надо бы заюзать calloc там.

crutch_master ★★★★★ ()
Последнее исправление: crutch_master (всего исправлений: 1)

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

Потому что в этом куске кода, как написал mittorn, ошибки нет.

А ещё, оформляй куски кода как надо в Markdown или LORCODE.

a1batross ★★★★★ ()
Ответ на: комментарий от crutch_master

Тогда можно попробовать (чисто в качестве теста, не для прода) в исходном тексте обеспечить два \0 вместо одного, ну и в malloc наговнокодить +2 вместо +1.

Если вдруг поможет (вот смеху-то будет) — копать дальше в этом направлении.

hobbit ★★★★★ ()
Ответ на: комментарий от Deleted

malloc ничего не затирает сам.

#include <stdio.h>
int main() {
    int cnt = 16;
    char *c = malloc(cnt);
    memset(c, 1, cnt);
    free(c);
    c = malloc(cnt);
    int i;
    for (i = 0; i < cnt; i++) {
        printf("%d", (int)c[i]);
    }
}
Выхлоп
0000000011111111

crutch_master ★★★★★ ()
Последнее исправление: crutch_master (всего исправлений: 2)
Ответ на: комментарий от crutch_master

Попробовал написать в конце функции out[strlen(string)] = ‘\0’;

Не помогло вообще, хотя символы отсекает нормально.

Полный код дать не могу, это строка GL_RENDERER, баг проявляется только в проприетарной программе в wine. Если я задаю static const string = "" то такого бага нет.

gradle ()
Ответ на: комментарий от crutch_master

?)

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

int main(int argc, char **argv) {
        for(int i = 0;i < 10000;i++) {
                char *s = malloc(i);

                // Ни разу fail не выведет
                for(int j = 0;j < i;j++) if(s[j]) puts("fail");

                for(int j = 0;j < i;j++) s[j] = j;
        }

        return 0;
}

Но я тебе про превращение цикла в memset, а не про malloc. Про malloc я уже сказал, strcpy пофиг что в первом аргументе.

Deleted ()