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

Memory Error while reading the string

// 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 = {'[=10=]'};
    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()。

此程序导致错误读取字符串字符时出错。我尝试了各种解决方案但无济于事。请帮忙。

一旦 allocatedLength 等于 logicalLength,TODO 部分用于增加 stack->elems 的大小。

free name 指向 在循环 内,它以静态分配开始,然后永远不会重新分配。

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

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 ,原因很明显,我之前没有注意到!