2010-08-27 3 views
2

Я пытаюсь определить путь во время компиляции путем пропускания:Ошибка сегментации при использовании strcpy?

-DDCROOTDEF='"/path/to/stuff"' 

на линии компиляции. Затем я попытаюсь использовать его в коде:

char * ptr_path; 
strcpy(ptr_path, DCROOTDEF); 
strcat(ptr_path,"/MainCommons/CommonLib/fonts/Arial.ttf"); 
char *pftf=ptr_path; 
gdImageStringFT(pimg,brect,iclr,pftf,pts,ang,ixp,iyp, (char *)cbuf); 

Это дает мне ошибку сегментации. Однако, если я попытаюсь напечатать строку сначала:

char * ptr_path; 
strcpy(ptr_path, DCROOTDEF); 
strcat(ptr_path,"/MainCommons/CommonLib/fonts/Arial.ttf"); 
char *pftf=ptr_path; 
printf("%s\n",pftf); 
gdImageStringFT(pimg,brect,iclr,pftf,pts,ang,ixp,iyp, (char *)cbuf); 

Это работает просто отлично. Какую сложность в указателе символов я не вижу здесь?

Благодаря

+0

Как насчет добавления '\ 0' в конце строки? – karlphillip

+1

@karlphillip: '\ 0' автоматически включается в конец строкового литерала. –

+0

+1 Это правда. – karlphillip

ответ

3
char * ptr_path; 
strcpy(ptr_path, DCROOTDEF); 

Вы никогда не инициализируют ptr_path.

Это не работает во втором фрагменте кода, вам просто не повезло, и он появляется для работы. Вы по-прежнему используете неинициализированный указатель и пытаетесь написать, кто знает, где в памяти.

Нужно инициализировать ptr_path, чтобы указать на массив char, длина которого не менее strlen(DCROOTDEF) + 1. Вы также должны проверить длину DCROOTDEF перед копированием ее содержимого в массив, чтобы быть уверенным, что он не слишком длинный. Вы можете сделать это вручную, используя strlen, или вы можете использовать функцию копирования с проверкой длины, такую ​​как strlcpy.

+0

strlcpy является нестандартным, не так ли? – Nyan

+0

@Nyan: 'strlcpy' является нестандартным. Вы можете легко [найти реализацию онлайн] (http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/lib/libc/string/strlcpy.c?rev=1.11;content-type= текст/обычный). –

+0

Если он работает, значит он работает. Одним из возможных результатов неопределенного поведения является поведение, к которому вы стремились в первую очередь. К сожалению. –

1

Указатель ptr_path не инициализирован, чтобы указывать на записываемую память, поэтому разворачивается его с помощью strcpy().

Вам необходимо позвонить, например. malloc() получить пространство, первое:

char * ptr_path = malloc(PATH_MAX); 

Или что-то подобное.

+0

, и вам нужно 'free()' память, когда вы закончите с ней. –

1

В

char * ptr_path; 
strcpy(ptr_path, DCROOTDEF); 
strcat(ptr_path,"/MainCommons/CommonLib/fonts/Arial.ttf"); 

указатель не связан с юридически выделенным блоком памяти, так что ваша программа работает в неопределенное поведение. Сначала необходимо выделить буфер, например, используя malloc(). Убедитесь, что буфер достаточно велик, чтобы удерживать результирующую строку вместе с завершающим нулевым символом.

Смежные вопросы