在结构中设置一个 const char 指针
Set a const char pointer in a struct
我正在尝试编写一个程序,我可以在其中创建令牌,使每个令牌都有一个常量类型和值。
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
token.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;
}
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "lib/token.h"
int main(int argi, char *argv[]){
const char th[] = "line", va[] = ":";
token *t = gen_token(th, va);
printf("(%s, %s)\n", t->type, t->value);
return 0;
}
当我运行正常时,似乎没有错误发生,但是当valgrind查看它时,它会抱怨很多。这是我的日志:
==4086== Memcheck, a memory error detector
==4086== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4086== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==4086== Command: ./a lol
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4E7FD4F: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Use of uninitialised value of size 8
==4086== at 0x4C2EBE2: strlen (vg_replace_strmem.c:458)
==4086== by 0x4E80D77: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Use of uninitialised value of size 8
==4086== at 0x4C2EBF4: strlen (vg_replace_strmem.c:458)
==4086== by 0x4E80D77: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4EAAEEB: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1307)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Use of uninitialised value of size 8
==4086== at 0x4EAAEF1: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1309)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4EAAF03: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1307)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Use of uninitialised value of size 8
==4086== at 0x4EAAF0D: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1309)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4C32EB3: is_overlap (vg_replace_strmem.c:137)
==4086== by 0x4C32EB3: __GI_mempcpy (vg_replace_strmem.c:1525)
==4086== by 0x4EAAE23: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4C32EB9: is_overlap (vg_replace_strmem.c:140)
==4086== by 0x4C32EB9: __GI_mempcpy (vg_replace_strmem.c:1525)
==4086== by 0x4EAAE23: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4C32EC7: __GI_mempcpy (vg_replace_strmem.c:1525)
==4086== by 0x4EAAE23: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4C32ECC: __GI_mempcpy (vg_replace_strmem.c:1525)
==4086== by 0x4EAAE23: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4C32F64: __GI_mempcpy (vg_replace_strmem.c:1525)
==4086== by 0x4EAAE23: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Use of uninitialised value of size 8
==4086== at 0x4C32F70: __GI_mempcpy (vg_replace_strmem.c:1525)
==4086== by 0x4EAAE23: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Use of uninitialised value of size 8
==4086== at 0x4C32F7E: __GI_mempcpy (vg_replace_strmem.c:1525)
==4086== by 0x4EAAE23: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086== (line, :)
==4086==
==4086== HEAP SUMMARY:
==4086== in use at exit: 0 bytes in 0 blocks
==4086== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==4086==
==4086== All heap blocks were freed -- no leaks are possible
==4086==
==4086== For counts of detected and suppressed errors, rerun with: -v
==4086== ERROR SUMMARY: 36 errors from 14 contexts (suppressed: 0 from 0)
如果对我的代码提出任何帮助 and/or 批评,我将不胜感激。
函数中
token *gen_token(const char *type, const char *val){
token o = {type, val}, *out = &o;
return out;
}
变量out
指向局部变量o
,配置在函数returns之后。这纯属偶然,您可以在调用函数后读取这些值。因此关于
的警告
Uninitialised value was created by a stack allocation
相反,您需要分配内存并将值复制到其中。 注意你需要记住在退出你的程序之前释放分配的内存,特别是如果你想让 valgrind 开心:)
您正在返回变量的地址 automatic storage duration in gen_token
function. For this kind of storage duration in c:
The storage is allocated when the block in which the object was declared is entered and deallocated when it is exited by any means (goto, return, reaching the end).
注意: 使用您从 gen_token
函数返回的地址是 未定义的行为.
我建议您在示例中使用 opaque pointer 技术,如下所示:
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;
}
在上面的示例中,gen_token
为 token
对象分配内存,初始化它,returns 分配内存块的地址。 c中的这种存储时长是分配的存储时长:
The storage is allocated and deallocated on request, using dynamic memory allocation functions.
示例用法:
#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;
}
还有一件重要的事情。 main
函数中的以下变量是具有自动存储持续时间的常量数组:
const char th[] = "line", va[] = ":";
您可以存储指向数组第一个元素的指针,但如果按如下方式进行,您将得到 dangling pointers:
token* create_token() {
const char th[] = "line", va[] = ":";
return gen_token(th, va);
} /* from this point the created 'token' object will store dangling pointers */
我正在尝试编写一个程序,我可以在其中创建令牌,使每个令牌都有一个常量类型和值。
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
token.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;
}
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "lib/token.h"
int main(int argi, char *argv[]){
const char th[] = "line", va[] = ":";
token *t = gen_token(th, va);
printf("(%s, %s)\n", t->type, t->value);
return 0;
}
当我运行正常时,似乎没有错误发生,但是当valgrind查看它时,它会抱怨很多。这是我的日志:
==4086== Memcheck, a memory error detector
==4086== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4086== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==4086== Command: ./a lol
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4E7FD4F: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Use of uninitialised value of size 8
==4086== at 0x4C2EBE2: strlen (vg_replace_strmem.c:458)
==4086== by 0x4E80D77: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Use of uninitialised value of size 8
==4086== at 0x4C2EBF4: strlen (vg_replace_strmem.c:458)
==4086== by 0x4E80D77: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4EAAEEB: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1307)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Use of uninitialised value of size 8
==4086== at 0x4EAAEF1: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1309)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4EAAF03: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1307)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Use of uninitialised value of size 8
==4086== at 0x4EAAF0D: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1309)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4C32EB3: is_overlap (vg_replace_strmem.c:137)
==4086== by 0x4C32EB3: __GI_mempcpy (vg_replace_strmem.c:1525)
==4086== by 0x4EAAE23: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4C32EB9: is_overlap (vg_replace_strmem.c:140)
==4086== by 0x4C32EB9: __GI_mempcpy (vg_replace_strmem.c:1525)
==4086== by 0x4EAAE23: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4C32EC7: __GI_mempcpy (vg_replace_strmem.c:1525)
==4086== by 0x4EAAE23: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4C32ECC: __GI_mempcpy (vg_replace_strmem.c:1525)
==4086== by 0x4EAAE23: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Conditional jump or move depends on uninitialised value(s)
==4086== at 0x4C32F64: __GI_mempcpy (vg_replace_strmem.c:1525)
==4086== by 0x4EAAE23: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Use of uninitialised value of size 8
==4086== at 0x4C32F70: __GI_mempcpy (vg_replace_strmem.c:1525)
==4086== by 0x4EAAE23: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086==
==4086== Use of uninitialised value of size 8
==4086== at 0x4C32F7E: __GI_mempcpy (vg_replace_strmem.c:1525)
==4086== by 0x4EAAE23: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==4086== by 0x4E80BBA: vfprintf (vfprintf.c:1637)
==4086== by 0x4E871F8: printf (printf.c:33)
==4086== by 0x1087AB: main (main.c:11)
==4086== Uninitialised value was created by a stack allocation
==4086== at 0x108785: main (main.c:10)
==4086== (line, :)
==4086==
==4086== HEAP SUMMARY:
==4086== in use at exit: 0 bytes in 0 blocks
==4086== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==4086==
==4086== All heap blocks were freed -- no leaks are possible
==4086==
==4086== For counts of detected and suppressed errors, rerun with: -v
==4086== ERROR SUMMARY: 36 errors from 14 contexts (suppressed: 0 from 0)
如果对我的代码提出任何帮助 and/or 批评,我将不胜感激。
函数中
token *gen_token(const char *type, const char *val){
token o = {type, val}, *out = &o;
return out;
}
变量out
指向局部变量o
,配置在函数returns之后。这纯属偶然,您可以在调用函数后读取这些值。因此关于
Uninitialised value was created by a stack allocation
相反,您需要分配内存并将值复制到其中。 注意你需要记住在退出你的程序之前释放分配的内存,特别是如果你想让 valgrind 开心:)
您正在返回变量的地址 automatic storage duration in gen_token
function. For this kind of storage duration in c:
The storage is allocated when the block in which the object was declared is entered and deallocated when it is exited by any means (goto, return, reaching the end).
注意: 使用您从 gen_token
函数返回的地址是 未定义的行为.
我建议您在示例中使用 opaque pointer 技术,如下所示:
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;
}
在上面的示例中,gen_token
为 token
对象分配内存,初始化它,returns 分配内存块的地址。 c中的这种存储时长是分配的存储时长:
The storage is allocated and deallocated on request, using dynamic memory allocation functions.
示例用法:
#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;
}
还有一件重要的事情。 main
函数中的以下变量是具有自动存储持续时间的常量数组:
const char th[] = "line", va[] = ":";
您可以存储指向数组第一个元素的指针,但如果按如下方式进行,您将得到 dangling pointers:
token* create_token() {
const char th[] = "line", va[] = ":";
return gen_token(th, va);
} /* from this point the created 'token' object will store dangling pointers */