LINUX.ORG.RU

Программа на Си падает, при выделении памяти


0

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

#define PASSES 100000

char *rline(int maxChars, FILE *stream) {
    char *buf = (char *)malloc(maxChars);
    fscanf(stream, "%s", buf);
    int len = strlen(buf);
    char *str = (char *)malloc(len);
    strcpy(str, buf);
    free(buf);
    return str;
}


int main() {
    time_t seed = time(NULL);
    FILE *in2 = fopen("strings.txt", "r");
    char **index2 = (char **) calloc(PASSES, sizeof(char *));
    srand(seed);
    printf("%d\n", (int)seed);
    for (int j = 0; j < PASSES; j++) 
        index2[j] = rline(65, in2);
        printf("Array 2 created!\n");
        return 0;
    }

На какой-то итерации цикла, программа падает, и выдает совершенно неведомую ошибку: 123: malloc.c:2369: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed. Аварийный останов

Хз что с этим делать, программа должна считать из файла строки в массив. Как это лечить? Вот тестовый файл: rghost


в

    int len = strlen(buf);
    char *str = (char *)malloc(len);
    strcpy(str, buf);
любимая ошибка всех времён и народов - не учтен \0

дальше не смотрел

MKuznetsov ★★★★★
()

fscanf(stream, «%s», buf);

Плохая идея. Если у тебя есть строка длиной более maxChars, ты затрешь память и вывалишься с такой вот неведомой ошибкой.

tailgunner ★★★★★
()

ну попробуй например

char *buf = (char *)malloc(maxChars+1);

или printf(«%d\n», len); после strlen

или там valgrind попробуй.

а потом прекрати использовать scanf, strlen и strcpy

dimon555 ★★★★★
()

Возможно, я неправ, но в твоём файле есть строки символов длиной 65, а в указателе строки нужно ещё завершающий NULL или '\0' записывать, то есть buf должен быть как минимум длиной 66.

С другой стороны, я не знаю условия задачи, которую ты решаешь. Вполне вероятно, что в файле есть строки длинее 65 байт. *scanf функции не лучший способ чтения файлов. Лучше используй fgets и реализуй «блочное» чтение, это спасёт от проблем с выделением памяти.

nickleiten ★★★
()
Ответ на: комментарий от Anvill

Строки гарантированно меньше 64 символов

>>> s_more_64 = 0
>>> fff = open('strings.txt', 'r')
>>> for fs in fff:
...     if len(fs) > 64:
...         s_more_64 += 1
... 
>>> s_more_64
1621

ну конечно ))

dimon555 ★★★★★
()
Ответ на: комментарий от dimon555

1.Меньше равно 64 символов 2.Питон считает \n за символ

Anvill
() автор топика

всё равно не спится :

/* прочесть файл построчно в массив */
int rlines(char **arr,int sz,FILE *f) {
  struct stat st;
  char *s;
  int t;
  // read whole file
  if (fstat(fileno(f),&st)!=0)
      return 0;
  s=arr[0]=malloc(st.st_size+1);
  if (s==NULL)
      return 0;
  if (fread(s,st.st_size,1,f)!=1) {
      free(arr[0]);
      return 0;
  }
  s[st.st_size]=0;
  // parse by strings
  for(t=1,s+=strcspn(s,"\n");*s && t<sz;s+=strcspn(s,"\n")) {
     *s++=0;
     arr[t++]=s;
  }
  return t;
}
не проверял, но должно работать :)

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

Вероятно, я туп, но я не понимаю, как это должно работать p.s не проверял

Anvill
() автор топика
Ответ на: комментарий от MKuznetsov

Пока ехал в маршрутке разобрался с этим кодом, оказалось не так страшно, как выглядит

Anvill
() автор топика
Ответ на: комментарий от MKuznetsov
// Там, где так:
arr[t++]=s;
// Должно быть так:
(*arr)[t++]=s;
// А разыменовывать указатель так - нехорошо:
arr[0];
// Надо так:
*arr;
kvap
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.