LINUX.ORG.RU

неожиданные глюки memcpy


0

0

Столкнулся с совершенно дурацкой проблемой.

void A (char *str)
{
char *dest = (char *)malloc (len);
if (!dest)
...
memcpy (dest, str, sz);
...
free (dest);
}

main ()
{
char *xxx = "abc";
A (xxx);
}

в результате в A() после memcpy содержимое dest имеет вид: "abc\004\b\004\b" плюс какой-то мусор. sz меньше len. Причем такая фигня иногда проявлятся, иногда нет. Компилятор - gcc, система FreeBSD 4.2. Может кто-то с чем-то подобным встречался или краем уха слышал.

anonymous

sz чему равен? strlen(str) или strlen(str)+1 А strcpy тебе не подойдет?

anonymous
()

sz равен strlen (str). Дело в том, что необходимо скопировать в dest лишь часть строки. Потому и использую memcpy. Меня больше всего удивляет то, что подобная конструкция иногда работает, иногда нет.

С уважением

anonymous
()

Nu, elki...

1. Otkuda beretsja len? A vdrug on bol'she razmera str?

2. A kto postavit terminiruushii '\0' v konec stroki? ne zabyt' len+1.

3. Est' krasivye funkcii tipa strncat() i strncpy(), za4em ogorod s memcpy() gorodit'?

4. Esli ho4etsja obnulennuu pamjat', to nado uzat' calloc(), ili malloc()+memset(*dest, 0, len).

5. A eshe strdup() est'....

BaT ★★★★★
()

А если попробовать так:

#include <stdio.h>
#include <malloc.h>

int len = 10;
int sz = 2;

void A(char *str)
{
char *dest;
if((dest = (char *)malloc(len)) == NULL)
exit(1);
memcpy(dest, str, sz);
dest[sz + 1] = '\0';
fprintf(stdout, "dest is: %s\n", dest);
free(dest);
}

int main(int argc, char **argv, char **argp)
{
char *xxx = "abc";
A(xxx);
}

Переменные sz, len и xxx изменить по вкусу :-)

Druker
()

Much more better :)

A vot contr-primer:

char *xxx="a\0bcd";
A(xxx);

4to ozhidaetsja v dannom slu4ae i sto budet vyvedenno?

Vpro4em, iz-za fprintf(%s) raznitca ne budet zametna...

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

Более того, если sz > len то наверняка будет seg. fault :-) Для fool-proof'ости не мешало бы определять if(sz > len) в начале и realloc'ать память под результат. А насчет char *xxx = "a\0что-то-там", то если далее не треба печатать строку printf'ом, то, собственно ничего необычного :-) Только тогда при дальнейшей обработке результата (после копирования memcpy'ом) надо также иметь в виду sz :) Ну а если печатать надо, то никто не мешает написать ф-цию printnf(size_t size, char *fmt, ...) :-))

Druker
()

memcpy -не добавляет нуля в конец строки, посему используй

memset(&dest,0, sizeof(dest)) or bzero и
memcpy(dest,str,sz);

или

strspy

Bulash-OFF
()
Ответ на: комментарий от Bulash-OFF

Да вроде как с memcpy разобрались :-) Вопрос насчет левых значений sz и всего кода в целом :-) Естественным было бы обьявить calloc() для обнуления выделенного пространства :о) Впрочем, при sz > len сия программа должна делать вывод, что копирование строки не состоится, т.к. исходная строка короче копии (ну, в кр. случае, копировать только sizeof(orig_string)а дальше забивать NULL). Вообще все зависит от логики приложения и этого куска кода в частности...

Druker
()

Ну вы господа здесь понарасписали. Я испоьзовал примерно тоже самое, что посоветовал Bulash-OFF. Все заработало.
Меня больше удивляло то, что конструкция, приведенная в самом начале темы, по большей части работала нормально; но иногда глючила. Совершенно необъяснимо. По крайней мере для меня. Вот если бы она совсем не работала... Ну в общем разобрались, всем спасибо.

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

int sz = 2; ... memcpy(dest, str, sz); // скопировал 2 байта dest[sz + 1] = '\0'; // поставил 0 на 2+1 индексе то есть на 4 позиции => 3-ий байт мусор.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.