C 在结构中设置常量字符指针

C 在结构中设置常量字符指针,c,string,struct,valgrind,C,String,Struct,Valgrind,我试图编写一个程序,在这个程序中,我可以创建令牌,这样每个令牌都有一个常量类型和值 token.h: #ifndef TOKEN_H #define TOKEN_H typedef struct{ const char *type; const char *value; }token; token *gen_token(const char *r, const char *val); #endif 标记c: #include <stdlib.h> #includ

我试图编写一个程序,在这个程序中,我可以创建令牌,这样每个令牌都有一个常量类型和值

token.h:

#ifndef TOKEN_H
#define TOKEN_H
typedef struct{
    const char *type;
    const char *value;
}token;

token *gen_token(const char *r, const char *val);

#endif
标记c:

#include <stdlib.h>
#include <string.h>
#include "lib/token.h"

token *gen_token(const char *type, const char *val){
    token o = {type, val}, *out = &o;
    return out;
}
如果您对我的代码有任何帮助和/或批评,我将不胜感激。

在函数中

token *gen_token(const char *type, const char *val){
    token o = {type, val}, *out = &o;
    return out;
}
变量
out
指向局部变量
o
,该变量在函数返回后处理。这纯属偶然,在调用函数后,您可以读取这些值。因此,有人警告

未初始化的值是由堆栈分配创建的


相反,您需要分配内存并将值复制到内存中注意在退出程序之前,您需要记住释放分配的内存,特别是如果您想让valgrind高兴:)

您正在使用in
gen_token
函数返回变量的地址。对于以下类型的存储持续时间:

当声明对象的块被输入时,存储被分配;当对象被退出时,以任何方式(转到、返回、到达终点)释放存储

注意:使用从
gen_token
函数返回的地址是一种未定义的行为

我建议您在示例中使用该技术,如下所示:

令牌.h

#ifndef TOKEN_H
#define TOKEN_H

struct token; /* incomplete type, but you can use pointers to it */
typedef struct token token;

/* allocates memory for 'token' and initializes it */
token* gen_token(const char* r, const char* val);
/* deallocates the specified memory */
void delete_token(token* ptr);
/* returns the value of 'type' member */
const char* get_type(token* ptr);
/* returns the value of 'value' member */
const char* get_value(token* ptr);

#endif
token.c

#include <stdlib.h>
#include "token.h"

/* the 'struct token' is defined here in the source file */
struct token {
    const char* type;
    const char* value;
};

token *gen_token(const char* type, const char* val) {
    token* out = (token*)malloc(sizeof(token));
    out->type = type;
    out->value = val;
    return out;
}
void delete_token(token* ptr) {
    free(ptr);
}
const char* get_type(token* ptr) {
    return ptr == NULL ? "" : ptr->value;
}
const char* get_value(token* ptr) {
    return ptr == NULL ? "" : ptr->type;
}

还有一件事很重要。
main
函数中的以下变量是具有自动存储持续时间的常量数组:

const char th[] = "line", va[] = ":";
您可以存储指向数组第一个元素的指针,但如果按如下操作,您将拥有:


什么是
out
?不要返回指向局部变量的指针。
标记o
是局部自动变量。这在范围外无效。因此我应该在main中创建令牌,并传递指向我的gen_token func的指针?不,您可以在函数内创建令牌,但只需要在heap上为其分配内存,out=malloc(sizeof(toke))。。。然后将值复制到结构字段中,例如out->value=malloc(strlen(value));strcpy(out->value,value),类型相同。在return语句之前,需要释放分配的内存,例如free(out->value);自由(输出->类型);免费(外出);我将通过提问来阐述我的解释。
#include <stdio.h>
#include <stdlib.h>
#include "token.h"

int main() {
    token* t = gen_token("line", ":");
    printf("(%s, %s)\n", get_type(t), get_value(t));
    return 0;
}
const char th[] = "line", va[] = ":";
token* create_token() {
    const char th[] = "line", va[] = ":";
    return gen_token(th, va);
} /* from this point the created 'token' object will store dangling pointers */