读取字符串时出现内存错误

时间:2015-02-24 14:05:45

标签: c pointers

// 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()替换_getch(),或者如果在UNIX系统上运行程序,则完全删除头文件和getch()

此程序在读取字符串字符时会导致错误错误。我尝试过各种各样的解决方案,但无济于事。请帮忙。

一旦allocateLength等于logicalLength,TODO部分用于增加stack-&gt; elems的大小。

3 个答案:

答案 0 :(得分:1)

free name指向循环中的,其中以静态分配开头,然后永远不会重新分配。

答案 1 :(得分:0)

您将name传递到stackPop函数,并将其用作memcpy的目标。但是,它没有正确分配,它太小了。

答案 2 :(得分: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 - &gt; (logLength - 1)而不是stringStack - &gt; logLength原因显而易见,我之前没有注意到!