[英]freeing char pointer in c causes segfault
The subject says all, here's the relevant code written in a simple file. 主题说了全部,这是用简单文件编写的相关代码。
char* fn = NULL;
SDL_Log("fn pre address is: %p\n",fn);
fn = get_resource("test.txt");
SDL_Log("fn pos address is: %p\n",fn);
//free(fn); <--this causes seg fault if I uncomment it
INFO: fn pre address is: 0x0
INFO: fn pre address is: 0x7fa882501a00
INFO: fn pos address is: 0x7fa882501a00
get_resource(const char* filename) {
char* string = (char*)calloc(1, sizeof(strlen(res_dir) + strlen(filename)));
//i also tried with strncpy
//strncpy(string, res_dir, strlen(res_dir));
//strncpy(string + strlen(res_dir), filename, strlen(filename));
memcpy(string, "/usr/test/files", strlen(res_dir));
memcpy(string + strlen("/usr/test/files"), filename, strlen(filename));
string[strlen(filename) + strlen("/usr/test/files")] = '\0';
return string;
}
getting the same behavior. 得到相同的行为。 If I free the allocated string I will get a seg fault.
如果释放分配的字符串,将出现段错误。 Also it doesn't always happen either which is strange.
而且这也不总是总是发生,这很奇怪。
char* string = (char*)calloc(1, sizeof(strlen(res_dir) + strlen(filename)));
This line doesn't make any sense, sizeof
is an operator for determining the storage size needed for a type or an expression of some type.(*) 这行没有任何意义,
sizeof
是用于确定类型或某种类型的表达式所需的存储大小的运算符。(*)
What you want is something like: 您想要的是这样的:
char* string = calloc(1, strlen(res_dir) + strlen(filename) + 1);
Note the + 1
there, it reserves space for the terminating 0
byte in a c-style string. 注意那里的
+ 1
,它为c样式字符串中的终止0
字节保留空间。 Also note casting of a void *
pointer (as returned by malloc()
and friends in C) doesn't make sense. 还请注意,强制转换
void *
指针(由malloc()
和C中的朋友返回)是没有意义的。 It's necessary in C++, but in C, void *
is the generic pointer type and implicitly converts to any other data pointer type. 在C ++中这是必需的,但是在C中,
void *
是通用指针类型,并且隐式转换为任何其他数据指针类型。
Digging further into your code (as per alk's comment) ... I guess res_dir
is just "/usr/test/files"
? 进一步挖掘您的代码(按照alk的注释)...我想
res_dir
只是"/usr/test/files"
? You might be missing a slash here (depending on the contents of your filename
) but in general, for concatenating strings, there is already a function in the C language, declared in string.h
. 您可能在此处缺少斜杠(取决于
filename
的内容),但通常,对于串联字符串,已经有C语言的函数在string.h
声明。 Just write something as simple as that: 只需编写如下简单内容:
char* string = calloc(1, strlen(res_dir) + strlen(filename) + 1);
strcpy(string, res_dir);
strcat(string, filename);
and you're done. 到此为止。 Note you don't even need
calloc()
with this method, malloc()
will do fine. 注意,您甚至不需要使用此方法的
calloc()
, malloc()
会很好。
(*) adding here even a bit more explanation: You probably see sizeof
quite often used with memory allocations, for obvious reasons. (*)在此处添加更多说明:由于明显的原因,您可能会看到
sizeof
经常与内存分配一起使用。 What you want is to reserve memory for the type char
. 您要为
char
类型保留内存。 And you want some count of char
s to fit into this memory. 您希望将一些
char
容纳到此内存中。 So, the correct formula for that would be something like: 因此,正确的公式如下所示:
malloc( (strlen(res_dir) + strlen(filename) + 1) * sizeof(char) )
Then why leave out the sizeof(char)
? 那为什么要忽略
sizeof(char)
呢? That's because the size of a char
is actually defined to be 1
. 这是因为
char
的大小实际上定义为1
。 x * 1
is still x
, so no need to use sizeof
here :) x * 1
仍然是x
,因此无需在此处使用sizeof
:)
First of all this statement 首先这句话
char* string = (char*)calloc( 1, sizeof(strlen(res_dir) + strlen(filename)));
is incorrect. 是不正确的。 Expression
表达
sizeof(strlen(res_dir) + strlen(filename))
is equivalent to 相当于
sizeof( size_t )
and can be equal either 4 or 8 depending on the used environment. 可以等于4或8,具体取决于使用的环境。 More over this expression
有关此表达式的更多信息
sizeof(strlen(res_dir) + strlen(filename))
is unevaluated . 没有被评估 。 That is function
strlen
is not called in this expression. 也就是说,该表达式中未调用
strlen
函数。
A correct statement can look like 正确的陈述看起来像
char *string = calloc( strlen( res_dir ) + strlen( filename ) + 1, sizeof( char ) );
Take into acount that you need also reserve memory for the terminating zero. 考虑到您还需要为终止的零保留内存。
However even this statement is incorrect.:) 但是,即使此语句也不正确。
Consider what you are trying to do 考虑你想做什么
memcpy(string, "/usr/test/files", strlen(res_dir));
memcpy(string + strlen("/usr/test/files"), filename, strlen(filename));
As you passed string "test.txt"
then you will get 当您传递字符串
"test.txt"
您将获得
"/usr/test/filestest.txt"
I think you mean instead the following 我想你的意思是以下
"/usr/test/files/test.txt"
If so then the memory allocation must look like 如果是这样,那么内存分配必须看起来像
char *string = calloc( strlen( res_dir ) + strlen( filename ) + 2, sizeof( char ) );
In this case you could write simply 在这种情况下,您可以简单地编写
strcpy( string, "/usr/test/files" );
strcat( string, "/" );
strcat( string, filename );
and in this case statement 在这种情况下,
string[strlen(filename) + strlen("/usr/test/files")] = '\0';
must be removed. 必须删除。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.