我正在尝试实现一个通用堆栈(一个单独的链表),除了必须处理字符数组之外,我已经解决了所有问题。
节点:
typedef struct cvor {
void *info;
struct cvor *next;
} Cvor;
堆栈typedef:
typedef struct {
Cvor *tos;
size_t velicinaInfo; //
freeFunction freeFn;
copyFunction copyFn;
} Stek;
初始化新堆栈的函数:
void noviStek(Stek *stek, size_t velInfo, freeFunction freeFn, copyFunction copyFn)
{
if (velInfo <= 0)
{
// element size can't be <=0
printf("Velicina elementa ne moze biti 0.\n");
return;
}
stek->tos = NULL;
stek->velicinaInfo = velInfo;
stek->freeFn = freeFn;
stek->copyFn = copyFn;
}
freeFunction
和copyFunction
的定义如下:
typedef void (*freeFunction)(void *);
typedef void (*copyFunction)(void **, void *);
对于基本类型(int
,double
,...)我不需要特定的复制功能,但我需要它用于char *。这就是我到目前为止所做的:
void copyString(void **dest, void *src)
{
char *psrc = (char*) src;
size_t size = strlen(psrc) + 1;
*dest = calloc(size, 1);
memcpy(*dest, src, size);
}
main看起来像这样:
char a[] = "helloooooooooo";
char b[] = "helloworld";
char c[] = "stringst";
Stek s;
noviStek(&s, sizeof(char*), NULL, copyString);
push(&s, a);
printf("tops: ");
stekTop(&s, pisi_string);
printf("\n");
push(&s, b);
printf("tops: ");
stekTop(&s, pisi_string);
printf("\n");
push(&s, c);
printf("tops: ");
stekTop(&s, pisi_string);
printf("\n");
//char d[100] = "";
char d[]="";
while (pop(&s, d))
{
printf("d = %s ", d);
}
isprazniStek(&s);
stekTop()
打印堆栈顶部,isprazniStek()
释放堆栈。
输出结果为:
tops: helloooooooooo
tops: helloworld
tops: stringstring
d =
d =
d =
因此,如果定义了copyFn
,则在调用push()
和pop()
来复制节点的信息内容时使用它(对于基本类型copyFn
是{ {1}})。
问题出在NULL
函数上,这是函数:
pop
它不会将int pop(Stek *stek, void *element)
{
if (isEmptyStek(stek))
return 0;
Cvor *p = stek->tos;
if (stek->copyFn)
{
stek->copyFn(&element, p->info);
}
else
{
memcpy(element, p->info, stek->velicinaInfo); // element = p->info;
}
stek->tos = p->next;
if (stek->freeFn)
{
stek->freeFn(p->info);
}
free(p->info);
free(p);
return 1;
}
复制到p->info
(当我使用element
时会这样做)并且它不会释放push()
。
我无法弄清楚原因。对不起,很长的帖子。任何帮助表示赞赏。
修改:
我将主要功能中的p=info
从d
更改为char d[]=""
,现在输出为:
char *d
EDIT2 :
因为我需要更改tops: helloooooooooo
tops: helloworld
tops: stringstring
d = (null)
d = (null)
d = (null)
我需要发送它的地址,这里是正确的代码:
d
以及char d[]="";
while (pop(&s, &d))
{
printf("d = %s ", d);
}
中的相应修正:
pop()
EDIT3 :
变量int pop(Stek *stek, void *element)
{
if (isEmptyStek(stek))
return 0;
Cvor *p = stek->tos;
if (stek->copyFn)
{
stek->copyFn(element, p->info); // <= !
}
...
必须单独释放以避免韭菜(感谢Valgrind):
d
答案 0 :(得分:0)
弹出代码应为:
char *d;
while (pop(&s, &d))
{
printf("d = %s ", d);
free(d);
}
pop
函数将弹出的值写入参数指向的内存。因此,您必须提供指向您编写弹出值的区域的指针。传递d
并不好,也没有将指针传递给1字节的char数组。
注意:这可能不是一个完整的答案。我认为你的pop
函数也是错误的,但你没有发布足够的代码。