gpt4 book ai didi

c - 在 C 中复制 char* 的通用函数

转载 作者:行者123 更新时间:2023-11-30 17:01:12 26 4
gpt4 key购买 nike

我正在尝试实现一个通用堆栈(一个单链表),除了必须处理字符数组之外,我已经解决了所有问题。

节点:

typedef struct cvor {
void *info;
struct cvor *next;
} Cvor;

堆栈类型定义:

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;
}

freeFunctioncopyFunction 定义如下:

typedef void (*freeFunction)(void *);
typedef void (*copyFunction)(void **, void *);

对于原始类型(intdouble,...),我不需要特定的复制函数,但我需要它用于 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);
}

主要看起来像这样:

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()时使用它来复制的信息内容节点(对于原始类型 copyFnNULL)。

问题出在 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

我不明白为什么。抱歉发了这么长的帖子。如有任何帮助,我们将不胜感激。

编辑:我将主函数中的 dchar d[]="" 更改为 char *d,现在的输出是:

tops: helloooooooooo 
tops: helloworld
tops: stringstring
d = (null)
d = (null)
d = (null)

编辑2:因为我需要更改 d 我需要发送它的地址,这是正确的代码:

char d[]="";
while (pop(&s, &d))
{
printf("d = %s ", d);
}

以及 pop() 中的相应修复:

int pop(Stek *stek, void *element)
{
if (isEmptyStek(stek))
return 0;

Cvor *p = stek->tos;

if (stek->copyFn)
{
stek->copyFn(element, p->info); // <= !
}

...

编辑3:变量d必须单独释放以避免韭菜(感谢Valgrind):

char d[]="";
while (pop(&s, &d))
{
printf("d = %s ", d);
// do something else with it
// ...
free(d);
}

最佳答案

弹出代码应该是:

char *d;

while (pop(&s, &d))
{
printf("d = %s ", d);
free(d);
}

pop 函数将弹出的值写入参数指向的内存中。因此,您必须提供一个指向写入弹出值的区域的指针。传递 d 是不好的,传递指向 1 字节字符数组的指针也是不好的。

注意:这可能不是完整的答案。我认为你的 pop 函数也是错误的,但你没有发布足够的代码。

关于c - 在 C 中复制 char* 的通用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37174060/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com