Проблемы с повреждением кучи - C - PullRequest
2 голосов
/ 19 июня 2019

Я делаю «простую» строку распечатки, добавляю строку и удаляю секцию из строки. Иногда работает команда добавления и новой строки, иногда ничего не выводится. Когда я делаю:

char * temp = malloc(newSize);

Он просто перестает выводить что-либо.

Я закомментировал все в разделах, пытаясь найти проблему. Кажется, не могу найти проблему, но Google продолжает придумывать «Повреждение кучи».

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char * data;
    int length;
} String;

int str_getLength(const char * characters)
{
    int index = 0;
    while (1)
    {
        if (characters[index] == '\0') break;
        index++;
    }
    return index;
}

String str_new(const char * characters) 
{
    String result;
    result.length = str_getLength(characters);
    result.data = malloc(result.length);
    memcpy(result.data, characters, result.length);
    return result;
}

void str_append(String * str, const char * characters) 
{
    int charsLength = str_getLength(characters);
    str->data = realloc(str->data, charsLength);
    for (int i = 0; i < charsLength; i++) {
        str->data[i + str->length] = characters[i];
    }
    str->length = str->length + charsLength;
}

void str_remove(String * str, int startIndex, int endIndex) 
{
    if (startIndex < 0 || endIndex > str->length || endIndex < startIndex) {
        return;
    }
    int chunkSize = endIndex - startIndex;
    int newSize = str->length - chunkSize;

    char * temp = malloc(newSize);
    // for (int i = 0; i < str->length; i++) 
    // {
    //  if (i < startIndex || i > endIndex) {
    //      temp[i] = str->data[i];
    //  } 
    // }

    // free(str->data);
    // str->length = newSize;
    // str->data = temp;
}
}

int main() 
{
    String str = str_new("Hello, ");
    printf("%s\n", str.data);

    str_append(&str, "this is my first C application.");
    printf("%s\n", str.data);

    str_remove(&str, 0, 3);
    printf("%s\n", str.data);

    free(str.data);

    return 0;
}

Я ожидал, что он выведет модифицированную строку, но это не так, а иногда ничего не выводится. Я новичок, извините, если это быстрое решение.

Ответы [ 2 ]

3 голосов
/ 19 июня 2019

Помимо безумного ответа.Есть еще несколько проблем.

// for (int i = 0; i < str->length; i++) 
// {
//  if (i < startIndex || i > endIndex) {
//      temp[i] = str->data[i];
//  } 
// }

Вы получите доступ вне границы для temp.Вам нужно поддерживать отдельный индекс для temp.

char * temp = malloc(newSize+1);
int k=0;
for (int i = 0; i < str->length; i++) 
 {
  if (i < startIndex || i > endIndex) {
      temp[k++] = str->data[i];
  } 
}
 temp[k] = '\0'; 
 free(str->data);
 str->length = newSize;
 str->data = temp;

И

Вы не null завершаете строку после добавления.

str->data = realloc(str->data, str->length + charsLength +1); //current length + new length + \0
for (int i = 0; i < charsLength; i++) {
    str->data[i + str->length] = characters[i];
}
 str->data[i + str->length] = '\0'; //null terminate the new string
str->length = str->length + charsLength;
3 голосов
/ 19 июня 2019

Есть две проблемы с вашим перераспределением.Прежде всего, вы не присваиваете результат realloc для str->data, поэтому, если память была перераспределена в другое место, tr->data впоследствии указывает на недопустимую память.Во-вторых, вы не добавляете размеры строки и добавляемой части, вы просто берете размер добавляемой части.

Это здесь

realloc(str->data, charsLength);

Должно быть:

str->data = realloc(str->data, charsLength + str->length + 1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...