2013-07-24 2 views
0

Я создаю массив (char *charheap;) длиной 32 байта в куче и инициализирую все элементы, которые должны быть \0. Вот моя главная функция:Возвращаем смежный блок в c

int main(void) { 
    char *str1 = alloc_and_print(5, "hello"); 
    char *str2 = alloc_and_print(5, "brian"); 
} 

char *alloc_and_print(int s, const char *cpy) { 
    char *ncb = char_alloc(s);// allocate the next contiguous block 
    if (ret == NULL) { 
    printf("Failed\n"); 
    } else { 
    strcpy(ncb, cpy); 
    arr_print();// print the array 
    } 
    return ncb; 
} 

Вот что я реализую:

/char_alloc(s): find the FIRST contiguous block of s+1 NULL ('\0') 
characters in charheap that does not contain the NULL terminator 
of some previously allocated string./ 

char *char_alloc(int s) { 
int len = strlen(charheap); 
    for (int i = 0; i < len; i++) { 
    if (charheap[0] == '\0') { 
    char a = charheap[0]; 
    return &a; 
} else if (charheap[i] == '\0') { 
    char b = charheap[i+1]; 
    return &b; 
    } 
} 
return NULL; 
} 

Ожидаемый результат: (\ означает \0)

hello\\\\\\\\\\\\\\\\\\\\\\\\\\\ 
hello\brian\\\\\\\\\\\\\\\\\\\\\ 

Это решение совершенно неправильно, и я просто печать две неудачные. :(

На самом деле, char_alloc должен возвращать указатель на начало смежного блока, но я не знаю, как реализовать это правильно. Может кто-нибудь дать мне подсказку или ключ?

+1

Что такое 'charheap'? –

+0

charheap [i] вместо charheap [0]? – Jiminion

+0

Здесь 'strlen (charheap)', вы не создали или не передали какой-либо массив charheap, как вы писали в вопросе – 0decimal0

ответ

3

Ваша функция возвращающая указатель на локальную переменную, поэтому вызывающий абонент получает указатель на недействительных памяти. Просто вернуть указатель в charheap, который является тем, что вы хотите.

return &charheap[0]; /* was return &a; which is wrong */ 

    return &charheap[i+1]; /* was return &b; which is wrong */ 

Ваш for цикл использует i < len условие завершения, но, так как charheap - \0 заполнено, strlen() вернет размер 0. Вы хотите итерации по всему charheap, поэтому просто используйте размер этого массива (32 в этом случае).

int len = 32; /* or sizeof(charheap) if it is declared as an array */ 

Это два исправление должно быть достаточно, чтобы получить программу вести себя, как вы ожидаете (см demonstration).

Однако вы не ставите чек, чтобы убедиться, что в вашей кучке достаточно места для принятия проверки распределения. Ваше распределение должно завершиться неудачно, если расстояние между началом доступной памяти и концом charheap меньше или равно желаемому размеру. Вы можете сделать это достаточно легко, установив len в качестве последней точки, которую вы хотите проверить, прежде чем узнаете, что не хватит места.

int len = 32 - s; 

Наконец, при попытке выделить третью строку, ваш цикл будет пропускать первую выделенную строку, но перезаписывает вторую выделенную строку. Логика цикла должна измениться, чтобы пропустить каждую выделенную строку. Вы сначала проверяете, является ли текущее местоположение в вашем charheap бесплатным или нет. Если это не так, вы продвигаете свою позицию по длине строки, плюс еще один, чтобы пропустить терминатор '\ 0' для строки. Если текущее местоположение бесплатное, вы его возвращаете. Если вы не можете найти свободное место, вы возвращаетесь NULL.

char *char_alloc(int s) { 
    int i = 0; 
    int len = 32 - s; 
    while (i < len) { 
    if (charheap[i] == '\0') return &charheap[i]; 
    i += strlen(charheap+i) + 1; 
    } 
    return NULL; 
} 
+0

Спасибо за ответ. Меня смущает «как вернуть указатель на начало смежного блока». – OKC

+0

Спасибо за помощь. Это работает хорошо, за исключением тех случаев, когда я пытаюсь вставить третью строку. Он просто заменяет вторую строку, но не продолжает вставку. Вы знаете, что случилось? – OKC

+0

Я думаю, что ошибка была частью вашей оригинальной программы. Вам действительно нужно пропустить каждую ранее выделенную строку. Это означает, что ваша логика цикла должна отличаться от написанной вами. – jxh

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