【发布时间】:2013-06-08 22:00:54
【问题描述】:
我有一个字符串函数,它接受指向源字符串的指针并返回指向目标字符串的指针。此功能目前有效,但我担心我没有遵循重新分级 malloc、realloc 和 free 的最佳做法。
我的函数的不同之处在于目标字符串的长度与源字符串的长度不同,因此必须在我的函数内部调用 realloc()。我通过查看文档知道...
http://www.cplusplus.com/reference/cstdlib/realloc/
内存地址在重新分配后可能会改变。这意味着我不能像 C 程序员那样“通过引用传递”其他函数,我必须返回新指针。
所以我的函数原型是:
//decode a uri encoded string
char *net_uri_to_text(char *);
我不喜欢我这样做的方式,因为我必须在运行函数后释放指针:
char * chr_output = net_uri_to_text("testing123%5a%5b%5cabc");
printf("%s\n", chr_output); //testing123Z[\abc
free(chr_output);
这意味着 malloc() 和 realloc() 在我的函数内部调用,而 free() 在我的函数外部调用。
我有高级语言(perl、plpgsql、bash)的背景,所以我的直觉是适当封装这些东西,但这可能不是 C 语言的最佳实践。
问题:我的方法是最佳实践,还是我应该遵循更好的方法?
完整示例
编译和运行时对未使用的 argc 和 argv 参数有两个警告,您可以放心地忽略这两个警告。
example.c:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *net_uri_to_text(char *);
int main(int argc, char ** argv) {
char * chr_input = "testing123%5a%5b%5cabc";
char * chr_output = net_uri_to_text(chr_input);
printf("%s\n", chr_output);
free(chr_output);
return 0;
}
//decodes uri-encoded string
//send pointer to source string
//return pointer to destination string
//WARNING!! YOU MUST USE free(chr_result) AFTER YOU'RE DONE WITH IT OR YOU WILL GET A MEMORY LEAK!
char *net_uri_to_text(char * chr_input) {
//define variables
int int_length = strlen(chr_input);
int int_new_length = int_length;
char * chr_output = malloc(int_length);
char * chr_output_working = chr_output;
char * chr_input_working = chr_input;
int int_output_working = 0;
unsigned int uint_hex_working;
//while not a null byte
while(*chr_input_working != '\0') {
//if %
if (*chr_input_working == *"%") {
//then put correct char in
sscanf(chr_input_working + 1, "%02x", &uint_hex_working);
*chr_output_working = (char)uint_hex_working;
//printf("special char:%c, %c, %d<\n", *chr_output_working, (char)uint_hex_working, uint_hex_working);
//realloc
chr_input_working++;
chr_input_working++;
int_new_length -= 2;
chr_output = realloc(chr_output, int_new_length);
//output working must be the new pointer plys how many chars we've done
chr_output_working = chr_output + int_output_working;
} else {
//put char in
*chr_output_working = *chr_input_working;
}
//increment pointers and number of chars in output working
chr_input_working++;
chr_output_working++;
int_output_working++;
}
//last null byte
*chr_output_working = '\0';
return chr_output;
}
【问题讨论】:
-
我喜欢
*"%"部分。 :D -
谢谢,我刚刚发现
'%'有效。 :) -
如果你在反引号(`)之间包裹你的代码,那么它们将被格式化为代码
-
这个
int int_length = strlen(chr_input); ... char * chr_output = malloc(int_length);看起来很危险。如果字符串在转换过程中没有收缩,则分配的内存太短了一个字节。字符串的0-terminator 无法保存。 -
那么
char * chr_output = malloc(int_length + 1);是正确的,这一行将被更改:chr_output = realloc(chr_output, int_new_length);到chr_output = realloc(chr_output, int_new_length + 1);对吗?