尝试实现一个简单的通用堆栈,我写了一堆堆栈溢出和分段错误:
21
一切正常但无法从void指针恢复我的int ...
分析其他实现我仍然不明白为什么我的工作不起作用。
在这里,我希望看到0 8240 842539056 842539056 842539056 842539056 842539056 842539056 842539056 842539056 842539056 842539056 842539056 842539056 842539056 842539056 842539056 842539056 842539056 842539056 842539056
次,但我得到了
Microsoft.SqlServer.Management.Smo.FailedOperationException: Apply to target server failed for Job 'Job1'. ---> Microsoft.SqlServer.Management.Common.ExecutionFailureException: An exception occurred while executing a Transact-SQL statement or batch. ---> System.Data.SqlClient.SqlException: The specified @server_name ('10.1.1.202') does not exist.
对于i大于20的每个值,如果i低于20
,则会出现漂亮的分段错误答案 0 :(得分:2)
您实际上并没有分配任何空间来保存实际数据,您只是为指向其他位置的指针分配空间。这不是一个非常有用的ADT。
我要做的是创建一个包含数据硬拷贝的堆栈:
typedef struct S {
void* data;
size_t size;
struct S* next;
} Stack;
然后必须更改这些功能:
Stack *pushStack(Stack *ptr, void *data, size_t size);
Stack *popStack(Stack *ptr, void *data, size_t* size); // return data and size
您可以改为创建一个这样的项目:
Stack *createStack (void* data, size_t size) {
Stack *tmp = malloc(sizeof(Stack));
tmp->data = malloc(size);
memcpy(tmp->data, data, size);
tmp->size = size;
tmp->next = NULL;
return tmp;
}
一旦你将设计改为如上所述,你就可以开始担心清除错误了。
答案 1 :(得分:2)
在此代码中:
for(i=0; i <= 21; i++) {
stackHandle = pushStack(stackHandle, &i);
}
你正在推动变量的地址(而不是值)&#34; i&#34; 21次。当您弹出弹出窗口时,您将检索此地址,当您打印它时,您可能达到22(当前值为&#34; i&#34;)。
答案 2 :(得分:1)
您会得到一些奇怪的值,因为您的ptr->content
值超出了范围。您应该为内容值分配内存。
试试这个:
for(i=0; i <= 21; i++) {
int* pi = new int;
*pi = i;
stackHandle = pushStack(stackHandle, pi);
}
<强>更新:强> 下面是更正的源代码(我测试了它并且它可以工作):
#include <stdlib.h>
#include <stdio.h>
#define nullptr NULL;
struct S {
void *content;
struct S *next;
};
typedef struct S Stack;
Stack *createStack() {
Stack *tmp = (Stack *)malloc(sizeof(Stack));
tmp->content = nullptr;
tmp->next = nullptr;
return tmp;
}
Stack *pushStack(Stack *ptr, void *content) {
Stack *newStr = createStack();
newStr->content = content;
newStr->next = ptr;
ptr = newStr;
return (ptr);
}
// parameter value is of type (void**) !!!
Stack *popStack(Stack *ptr, void **value) {
Stack *toDelete = ptr;
// In such a way we can return 'content' from the function.
// 'content' is a pointer and to return it from the function
// we should dereference pointer to a pointer 'value'
*value = (ptr->content);
ptr = ptr->next;
free(toDelete);
return (ptr);
}
Stack *stackHandle = nullptr;
void printStack(Stack *ptr) {
int *element;
int i;
for (i = 0; i <= 20; i++) {
ptr = popStack(ptr, (void**)&element); // pointer to apointer !!!
if (element) {
printf("%d ", *element);
// deallocate memory and escape memory leaks !!!
delete(element);
}
}
printf("\n");
}
int main() {
stackHandle = createStack();
int i;
for (i = 0; i <= 21; i++) {
int* pi = new int(i); // allocate memory !!!
stackHandle = pushStack(stackHandle, pi);
}
printStack(stackHandle);
}
主要修正。
int* pi = new int(i);