2015-02-24 5 views
-3
// Gurucharan Sharma 
// 24 February 2015 
// 
// Program to create a stack that can 
// push and pop (char *) or strings and 
// elements of other data types. 

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

#define TODO //TODO 

typedef struct { 
    void *elems; 
    int elemSize; 
    int logLength; 
    int allocLength; 
} stack; 

void stackNew(stack*, int); 
void stackPush(stack*, void *elemAddr); 
void stackPop(stack*, void *elemAddr); 
void stackDispose(stack*); 

int main() { 
    const char *friends[] = {"Al", "Bob", "Carl"}; 
    char *name = {'\0'}; 
    int i, j; 

    // Creating the new stack. 
    stack stringStack; 
    stackNew(&stringStack, sizeof(char *)); 

    // Pushing strings onto the stack. 
    for (i = 0; i < 3; i++) { 
     char *copy = _strdup(friends[i]); 
     stackPush(&stringStack, &copy); 
    } 

    // Poping the stack elements. 
    for (i = 0; i < 3; i++) { 
     stackPop(&stringStack, &name); 
     printf("%s\n", name);   // error is generated on this statement 
     free(name); 
    } 

    // Disposing off the stack memory. 
    stackDispose(&stringStack); 

    _getch(); 
    return EXIT_SUCCESS; 
} 

void stackNew(stack *stringStack, int elemSize) { 
    stringStack -> elemSize = elemSize; 
    stringStack -> logLength = 0; 
    stringStack -> allocLength = 3; 
    stringStack -> elems = malloc((stringStack -> allocLength) * elemSize); 
    assert((stringStack -> elems) != NULL); 
} 

void stackPush(stack *stringStack, void *elemAddr) { 
    void *target = (char *) (stringStack -> elems) + 
     (stringStack -> logLength) * (stringStack -> elemSize); 
    memcpy(target, elemAddr, stringStack -> elemSize); 
    (stringStack -> logLength)++; 
} 

void stackPop(stack *stringStack, void *elemAddr) { 
    void *source = (char *) stringStack -> elems + 
     (stringStack -> logLength) * (stringStack -> elemSize); 
    memcpy(elemAddr, source, (stringStack -> elemSize)); 
    (stringStack -> logLength)--; 
} 

void stackDispose(stack *stringStack) { 
    free(stringStack); 
} 

Эта программа была написана для GCC Visual Studio 2013. При работе в какой-то другой компилятор, пожалуйста, замените _getch() с Геч(), или если вы работаете с программой в системе UNIX, полностью удалите файл заголовка и getch().Ошибка памяти при чтении строки

Эта ошибка приводит к ошибке Ошибка при чтении символов строк. Я пробовал всевозможные решения, но безуспешно. Пожалуйста помоги.

Раздел TODO предназначен для увеличения размера стека -> elems, как только выделенная длина будет равна логической длине.

+2

'stackPush()' и 'stackPop()' сигнатуры функций не соответствуют их определению. –

ответ

0
void stackPop(stack *stringStack, void *elemAddr) { 
    void *source = (char *) stringStack -> elems + 
     (stringStack -> logLength - 1) * (stringStack -> elemSize); 
    memcpy(elemAddr, source, (stringStack -> elemSize)); 
    (stringStack -> logLength)--; 
} 

Я только что внесла изменения в функцию stackPop(), и ошибка исчезла!

Обратите внимание на заявление:

void *source = (char *) stringStack -> elems + (stringStack -> logLength - 1) * (stringStack -> elemSize); 

Я просто использовал stringStack -> (logLength - 1) вместо stringStack -> logLength по очевидным причинам, которые я не замечал раньше!

1

Вы free, что name указывает на внутри цикла, который начинается со статическим распределением, а затем никогда не будет перераспределена.

+0

Во-первых, я попытался объявить «имя» внутри цикла, но ошибка все еще существовала. Во-вторых, я попытался освободить имя за пределами цикла, но все же ошибка была там. –

+0

Вы никогда не выделяете его; почему ты когда-нибудь освободишь его? –

+0

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

0

Вы передаете name в функцию stackPop, где она используется как цель memcpy. Однако он не был правильно распределен, он слишком мал.