realloc () Ошибка - PullRequest
       1

realloc () Ошибка

1 голос
/ 01 февраля 2012

Я пытался реализовать простую функцию, которая может объединять любое количество передаваемых ей строк.Мой звонок на Realloc не удается.Это как-то связано с тем фактом, что строковые аргументы, которые я передаю функции, хранятся в сегменте данных, где realloc ищет выделение памяти из кучи?Это просто идея, которая у меня есть.Я новичок, поэтому извините, если это кажется глупым.Как я могу заставить эту функцию работать?

 //Program to implement a function that can concatenate any number of argumnets 

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

char *mstrcat(char *first, ...);
int main(int argc, int **argv){
    char *s;
    s=mstrcat("I ","Love ","Stack","Overflow");
    printf("%s\n",s);
}
char *mstrcat(char *first, ...){
       char *s=first,*p;
       int len=0;  // stores the length of the string as it grows
       len=strlen(s);
       va_list aptr; // creates a pointer to the unnamed argument list
       va_start(aptr,first); // initialise aptr to the first unnamed argument
       if(aptr==NULL){
        return s;
      }
      while((p=va_arg(aptr,char *))!=NULL){ // till there are no more arguments to process
         len+=strlen(p);
         if((s=(char *)realloc(s,len+1))!=NULL){
            strcat(s,p);
         }
         else{
            printf("Failed to concatenate\n");    
            return first; 
         }
      }
      return s;
}

Ответы [ 4 ]

2 голосов
/ 01 февраля 2012

Ваш код имеет неопределенное поведение . Стандарт предписывает, чтобы указатель, передаваемый на realloc, точно совпадал с указателем, который был выделен динамической памяти с использованием функции управления памятью. Функции управления памятью, определенные стандартом:
aligned_alloc, calloc, malloc и realloc.

Указатель, который вы передаете realloc(), не был возвращен ни одним из них и, следовательно, неопределенным поведением.

Справка:
c99 standard: 7.22.3.5 Функция realloc

Синопсис: # 1

#include <stdlib.h>
void *realloc(void *ptr, size_t size);

# 3

Если ptr является нулевым указателем, функция realloc ведет себя как функция malloc для указанный размер. В противном случае , если ptr не соответствует указателю, ранее возвращенному памятью. функция управления, или если пространство было освобождено путем вызова функция realloc, поведение не определено . Если память для нового объекта не может быть после выделения старый объект не освобождается, а его значение не изменяется.

0 голосов
/ 01 февраля 2012

функция mstrcat начинается с s, указывающего на первый аргумент.Затем вы пытаетесь realloc () этот указатель, который является статической строкой.Это не будет работать.Вы можете перераспределить только указатель, ранее выделенный функцией malloc ().

Я предлагаю изменить char *s=first на char *s=strdup(first), чтобы выделить копию первого аргумента, и тогда этот код должен работать.

Алгоритм конкатенации довольно неэффективен, но это уже другая история ... (подсказка: вы можете перечислить аргументы и отследить общий размер, затем выделить () соответствующий буфер и затем объединить все аргументы в него)

0 голосов
/ 01 февраля 2012

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

realloc canиспользоваться только с указателем, ранее возвращенным malloc или realloc.Другие виды использования (как и ваше) приводят к неопределенному поведению.

0 голосов
/ 01 февраля 2012

Точка около realloc, аргумент size - это новый размер выделенных данных, который для вас должен быть старой длиной s плюс длина p (+1 для терминатор конечно).

И, как вы подозреваете, вы не можете использовать строку first в качестве основы для перераспределения. Вместо этого установите s в NULL в начале функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...