2015-12-16 3 views
0

Так вот код, содержащий printf (с номерами строк, это от think.c):C: Возвращаясь обугленного * из функции врезается Printf

30: char *think = getRandomMemory(); 
31: printf("\33[2K\r"); 
32: if(think == NULL) 
33:  think = "NULL"; 
34: printf("I have an idea: %s\n", think); 
35: parse(think); 
36: freeMemory(think); 
37: printf("> "); 

И код из getRandomMemory() который удостоверяется вернулся указатель указывает на кучу выделенного пространства:

char *getRandomMemory() 
{ 
    char *ret; 

    // --SNIP-- 

    size_t l = strlen(ret) + 1; 
    char *rret = getMemory(sizeof(char) * l); 
    for(int i = 0; i < l; i++) 
     rret[i] = ret[i]; 
    printf("--- %s ---\n", rret); 
    return rret; 
} 

И, наконец, это то, что gdb дает мне при запуске этого. Обратите внимание, что «--- тест ---» происходит от «printf("--- %s ---\n", rret)» выше:

(gdb) run 
Starting program: /home/v10lator/Private/projekte/KI/Lizzy 
[Thread debugging using libthread_db enabled] 
Using host libthread_db library "/lib64/libthread_db.so.1". 
Loading Lizzy 0.1... Done! 

> --- test --- 
[New Thread 0x7ffff781f700 (LWP 32359)] 

Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 0x7ffff781f700 (LWP 32359)] 
0x00007ffff7869490 in _IO_vfprintf_internal (s=<optimized out>, format=<optimized out>, 
[email protected]=0x7ffff781ee68) at vfprintf.c:1642 
1642 vfprintf.c: Datei oder Verzeichnis nicht gefunden. 
(gdb) bt 
#0 0x00007ffff7869490 in _IO_vfprintf_internal (s=<optimized out>, format=<optimized out>, 
[email protected]=0x7ffff781ee68) at vfprintf.c:1642 
#1 0x00007ffff7919235 in ___printf_chk (flag=1, format=<optimized out>) at printf_chk.c:35 
#2 0x00000000004016bc in printf() at /usr/include/bits/stdio2.h:104 
#3 run (first=<optimized out>) at think.c:34 
#4 0x00007ffff7bc64c6 in start_thread (arg=0x7ffff781f700) at pthread_create.c:333 
#5 0x00007ffff790a86d in clone() at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109 

Я действительно не знаю, что здесь не так, так что надеюсь, кто-то видит ошибку.

// EDIT: Забыли GetMemory/FreeMemory функции:

/* 
    * This allocates memory. 
    * The difference between usig malloc directly is that this function will 
    * print an error and exit the program in case something bad happens. 
    */ 
char *getMemory(size_t size) 
{ 
    char *mem = malloc(size); 
    if(mem == NULL) 
     crashWithMsg("Internal error (malloc failed)!"); 
    return mem; 
} 

/* 
* This deallocates memory. 
* The difference between using free directly is that this function will 
* set the pointer to NULL afterwards. 
*/ 
void freeMemory(void **ptr) 
{ 
    free(*ptr); 
    *ptr = NULL; 
} 
+0

В 'getRandomMemory':' rret [i] = ret [i]; '-' ret' не указывает на какую-либо правильно инициализированную память, поэтому у вас есть UB (также: 'size_t l = strlen (ret) + 1; '). – szczurcio

+0

Вы * do * инициализируете 'ret' в правильную строку с надлежащим завершением? –

+0

Можете ли вы рассказать нам (или, вернее, * показать нам), что делает 'getMemory'? –

ответ

0

Проблема заключается в том, чтобы ваш звонок freeMemory:

freeMemory(think); 

Вы закодированы эту функцию, чтобы получить адрес указателя чтобы освободить память, а не сам указатель. Таким образом, вы должны вызвать его:

freeMemory(&think); 
+0

Спасибо за головокружение, но программа рушится, прежде чем она дойдет до вызова 'freeMemory'. – Thomas

+0

Я вижу. Не уверен, что происходит, но я также заметил, что вы иногда назначаете фиксированную строку «NULL» '' think', прежде чем освобождать ее. Это также вызовет ошибку памяти. Но похоже, что ваша проблема возникает до этого. –

+0

@Thomas И вы не называли 'freeMemory' неправильным способом * до * этого кода? Вы не запускаете свой код в цикле? –

-1

[Удалено искажены утверждение]

Почему бы не использовать strcpy()?

+0

Посмотрите, как OP вычисляет длину строки и как копирует OP. Если в исходной строке есть терминатор, он будет скопирован. Но да, OP должен был использовать 'strcpy' вместо этого. –

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