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

时间:2016-05-11 22:06:10

标签: c generics stack void-pointers

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

节点:

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

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

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=infod更改为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

1 个答案:

答案 0 :(得分:0)

弹出代码应为:

char *d;

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

pop函数将弹出的值写入参数指向的内存。因此,您必须提供指向您编写弹出值的区域的指针。传递d并不好,也没有将指针传递给1字节的char数组。

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