Професионална програма
Loading...
+ Нов въпрос
agogo avatar agogo 12 Точки

C programming: Възможно ли е?

Здравейте!

Искам да ви запитам дали следното присвояване е коректно и кога би предизвикало вероятна грешка:

// Това е една от примерните задачи в курса:

// Да се съединят всички низове в масива, разделени чрез даден символ.

int main()

{

             char *delim = ", ";

             char *to[10] = { "Plovdiv","Sofia" ..., " "};

             char *result = join(to,length,delim);

             .......

}

char * join(char *to[], site_t size,char *delim)

{

             char *p = strcat(to[0],delim);

             ........

            return p;

}                                        

// Идеята ми тук, е да се избегне предварително използване на malloc или calloc, а директно да се използва първия низ от масива.

// В случая примерът сработва!

// Според описанието на strcat, се връща указател към низ. Но дали по посочения начин се работи с копие на този низ (понеже се предава // на функция ) или  не! Искам да попитам това не е ли явно задаване на низ от тип char *p = string; (може би без '\0')

Благодаря!

1
C Programming 26/01/2016 16:22:02
fristgerb avatar fristgerb 50 Точки

Здрасти! :)

кога би предизвикало вероятна грешка

Винаги. Опита ли се поне веднъж да пуснеш кода, който си написал? :)

Програма ти се разваля при strcat (to[0], delim); понеже се опитваш да модифицираш низа "Plovdiv", но той не бива да се променя. Такива низове операционната система ги слага в памет, която е read-only за твоята програма. Когато се опитваш да пишеш по тази read-only памет, получава "Segmentation Fault" и процесът ти бива терминиран.

Паметта на стартираната програма изглежда така:

 

   Process Memory
+-------------------+
|stack:             |
|  char *to[2] = {  |
|    0x01, >--------+-----+
|    0x02, >--------+---+ |
|  };               |   | |
|                   |   | |
+-------------------+   | |
|heap:              |   | |
|                   |   | |
+-------------------+   | |
|read-only:         |   | |
|  "Plovdiv\0" <----+---+-+
|  "Sofia\0" <------+---+
|                   |
+-------------------+
5
26/01/2016 14:02:27
agogo avatar agogo 12 Точки

Извинявам се!

Неправилно съм показал примера, сега съм го редактирал!

Според http://www.delorie.com/djgpp/doc/libc-2.02/libc_640.html strcat връща указател.

Дали този указател не може да се използва по посочения начин.

Посочения пример работи, но дали е коректно и дали да се избягва?

1
26/01/2016 15:10:20
denka avatar denka 52 Точки

Здравей,

Указателя, който връща strcat сочи към първия елемент на първия параметър на strcat. Т.е.

char * ptr = strcat(str1, str2);

Тук ptr и str сочат на едно и също място в паметта. - Функцията не събира str1 и str2  в ptr, а добавя str2 в края на str1.

Дали може да го върнеш като резултат от функция или не зависи от това къде е паметта на str1 - ако е в heap-a няма проблем, но ако е в стека ще се замаже при излизане от функцията:

char * test1() {

char * str1 = malloc(200);

......

return strcat(str1, str2); } е ОК,

но

char * test1() {

char str1[200];

......

return strcat(str1, str2); } не е ОК

Иначе за самия код който си написал, наистина няма как да работи, защото както ти е казал колегата, to[0]  е в read only паметта, а strcat се опитва да го модифицира.

Също така имай впредвид, че в str1 трябва да има достатъчно памет за конкатинацията. Тоест ако в примера който съм написала се опитам да конкатинирам стрингове с размери 100 и 150 ще има проблем, защото паметта на str1 е само 200.

В някоя от лекциите бяха казали за valgrind програмката. Много е полезна и ти препоръчвам винаги да се тестваш кода с нея.

 

 

2
agogo avatar agogo 12 Точки

Здравейте и благодаря!

Ето целия код, където използвам въпросното присвояване http://tjelev.free.bg/work/zd6.c и макар той да сработва в DJGPP(FREEDOS) и GCC(LINUX), когато проверих с Valgrind се появиха грешките за които писахте.

Явно не може да се избегне malloc и calloc.

Искам да попитам има ли подобна програма на Valgrind и за FREEDOS - не успях да открия в Интернет!

Лека и спокойна!

 

1
26/01/2016 18:48:29