读取字符串时出现内存错误 [英] Memory Error while reading the string

查看:92
本文介绍了读取字符串时出现内存错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#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;
	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, ©);
	}

	// Poping the stack elements.
	for (i = 0; i < 3; i++) {
		stackPop(&stringStack, &name);
		printf("%s\n", name);        // error is generated here
		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 -> elems);
}

推荐答案

您的代码中存在很多歧义。

如:

在stackNew函数上你传递了sizeof(char *)

sizeof任何指针都会返回4.



你试图释放stringStack,但你永远不会分配它。你已经在stackPop函数中分配了stringStack-> elems



如果你仔细看看你已经分配了变量名,那么你试图将值设置为elemAddr传递给stackPop函数。



另一个问题是:这不是堆栈如何工作。您可能需要在课堂和教科书上多加注意。
You have lots of ambiguity in your code.
Such as:
On stackNew function you have passed sizeof (char*)
sizeof any pointer will return 4.

you tried to free stringStack but you never allocate it. You have allocated stringStack->elems

in stackPop function you are trying to set value to elemAddr if you give a careful look at no point you have allocated variable name which is passed to stackPop function.

Another issue would be: This not how stack work. You may need to pay more attention at your class and textbook.


了解VS C ++上的幻数:请参阅 Visual C ++中的幻数 [ ^ ]。



您尝试使用一种不支持此语言的语言非常通用。

您必须使用 void 指针和书籍保留元素的长度,投入和反复很多。只是不可维护。



你的代码除了上面的常规代码之外还有其他一些缺陷。

例如处置不涉及处理存储的元素等。



如果我必须在C中编写堆栈,我将以开头int stack。

如果我掌握了这个,我会去 char [] (即 char * )堆栈,我必须处理内存所有权(你必须决定谁拥有传递的元素 - 你在内部复制还是要求客户端代码复制,堆栈释放在处理堆栈,或堆栈不拥有元素,或任何其他(更加模糊)的方案?))。



只有这样我才会去做一般的 - 目的堆栈类(如果真的真的真的需要!)。然后你必须明确如何在一个引擎盖下带来 int stack char * stack 。 />


由于您已使用C ++标记了问题,请转到并使用 std :: stack 类。你在这里重新发明轮子。只有作为练习才有理由这样做是浪费时间;-)。



干杯

Andi
Learn about the magic numbers on VS C++: see Magic Numbers in Visual C++[^].

You try to be very generic in a language that does not really support this.
You have to employ void pointers and book keeping length of elements, cast forth and back a lot. Just not maintainable.

Your code has several other flaws beside the general ones above.
E.g. Disposing does not deal with disposing the stored elements, etc.

If I had to program a stack in C, I'd start with an int stack.
If I master this, I would go for a char[] (i.e. char*) stack where I had to deal with memory ownership (you have to decide who owns the passed element - do you duplicate internally or do you require the client code to duplicate and the stack frees at disposing the stack, or the stack does not own the element, or any other (more obscure) scheme?)).

Only then I would go to do a general-purpose stack class (if really really really needed!). Then you have to make clear how you can bring the int stack and the char* stack under one hood.

Since you have tagged the question with C++, go and use the std::stack class. You re-invent the wheel here. Only justifiable as an exercise to learn that doing so is waste of time ;-).

Cheers
Andi


我刚刚对stackPop()函数做了一些更改



I just made a few changes to the stackPop() function

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





请注意声明:



Notice the statement:

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



I只是因为显而易见的原因而使用(logLength - 1),我之前没有注意到。


I just had to use (logLength - 1) for obvious reasons, that I failed to notice before.


这篇关于读取字符串时出现内存错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆