Основная проблема заключается в том, что вы не понимаете разницу между копированием / назначением указателей и копированием / назначением данных, на которые они указывают .Во-вторых, кажется, вы можете не оценить полезность указателей, которые ни на что не указывают, особенно нулевые указатели.Далее следуют некоторые детали.
Вы динамически распределяете пространство для набора строк ...
for(int idx = 0; idx < d->size; idx++)
{
d->deque[idx] = (char *)malloc((MAX+1) * sizeof(char));
... и затем пропускаете все этозаменив указатель на каждый указатель на пустой строковый литерал:
d->deque[idx] = "";
}
Как будто утечка не была достаточно плохой, вам не разрешено освобождать строковый литерал илиизмените его содержимое, что вы тем не менее пытаетесь сделать с любым из тех указателей, которые остаются в очереди, когда вы его clear()
.Вероятно, это является причиной некоторых ваших ошибок.
Если вы хотите установить каждую выделенную строку на пустую, то измените ее content вместо замены указателя на нее.Например:
d->deque[idx][0] = '\0';
На самом деле, однако, вам, вероятно, не нужно даже этого делать.Вы уже ведете бухгалтерию, чтобы знать, какие массивы содержат действительные (строковые) данные, а какие нет, и этого должно быть достаточно для правильной работы.Предположим, вы в первую очередь храните копии строк.
Но это еще не все.Когда вы добавляете rAppend()
элементов в вашу деку, у вас возникает похожая проблема.Вы создаете временную деку, а затем копируете строку указатели из оригинальной декы во временную:
dTemp.deque[idx] = d->deque[idx];
Это не только утечка оригинала (пусто)) данные во временной деке, она совмещает содержимое этой декы с основной декой.Когда вы позже очищаете временную деку, вы освобождаете все строковые указатели в оригинале.Последующее их использование или освобождение приводит к неопределенному поведению.
Возможно, вы вместо этого захотите strcpy()
всех элементов основного deque в temp и обратно, но я предлагаю вместо этого пропустить временный deque вместе с чем-то в этом направлении:
void rAppend(deque *d, char item[]) // as in rear append - same enqueue for queue structure.
{
if(isFull(d))
{
printf("Is Full\n");
char **tmp = realloc(d.deque, d->size * 2);
if (tmp)
{
d->deque = tmp;
for (int i = 0; i < d->size; i++)
{
// Copied from the original, but see below
d->deque[d->size + i] = malloc( sizeof(char) * MAX );
}
d->size * 2;
} // else?
}
printf("Appending to rear.. %s\n", item);
d->pRear++;
// Oops, this is another leak / aliasing issue:
d->deque[d->pRear] = item;
if(d->pFront == -1)
d->pFront = 0;
}
Весь смысл временной deque для меня потерян, так как realloc()
, который вам нужно сделать, сохраняет исходные данные в любом случае (до тех пор, пока это удается, в любом случае).
Обратите внимание, однако, что это все еще имеет проблему псевдонимов: вы связали элемент deque с добавленной строкой и вытекли из памяти, выделенной для этого элемента.Кроме того, когда вы очищаете deque, вы освобождаете эту строку для всех, кто держит указатель на нее.Или, по крайней мере, вы пытаетесь это сделать.Вам не разрешено делать это со строковыми литералами.
Я предлагаю вообще не выделять место в вашей деке для отдельных строк и не освобождать его.Продолжайте использовать назначение для хранения элементов в вашей deque, понимая и понимая, что это псевдонимы.Это будет более аналогично вашей реализации для int
s.