小编Mic*_*ael的帖子

在c中返回可变长度字符串的最佳实践

我有一个字符串函数,它接受指向源字符串的指针并返回指向目标字符串的指针.这个功能目前有效,但我担心我没有遵循重新编写malloc,realloc和free的最佳实践.

与我的函数不同的是,目标字符串的长度与源字符串不同,因此必须在我的函数内调用realloc().我从查看文档中了解到......

http://www.cplusplus.com/reference/cstdlib/realloc/

realloc后内存地址可能会改变.这意味着我不能像C程序员那样"通过引用"传递给其他函数,我必须返回新的指针.

所以我的功能原型是:

//decode a uri encoded string
char *net_uri_to_text(char *);
Run Code Online (Sandbox Code Playgroud)

我不喜欢我这样做的方式,因为我必须在运行函数后释放指针:

char * chr_output = net_uri_to_text("testing123%5a%5b%5cabc");
printf("%s\n", chr_output); //testing123Z[\abc
free(chr_output);
Run Code Online (Sandbox Code Playgroud)

这意味着在我的函数中调用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 …
Run Code Online (Sandbox Code Playgroud)

c string function

9
推荐指数
1
解决办法
1849
查看次数

clang/gcc优化密码变量清除功能

我们担心恶意程序会尝试从RAM中读取密码.所以我们写了一个函数来覆盖密码变量,然后释放它.我们担心的是像clang或gcc这样的智能编译器会优化这个函数中的代码.该函数将字符串中的每个字符更改为空字节,然后释放该变量.

void free_pword(char* pword) {
    char* pword_original = pword;
    char c;

    while ((c = *(pword++))) {
        *pword = '\0';
    }

    free(pword_original);
}
Run Code Online (Sandbox Code Playgroud)

现在我们的问题.我们需要这样做吗?如果没有,为什么?如果我们确实需要这样做,我们怎样才能确保覆盖不会被优化掉?

###########编辑1:(2015年2月11日)

来自未来的亲爱的人:这是我们到目前为止已经想到的......

我查看了原始汇编代码(来自gcc)以确定代码是否被优化掉了,事实并非如此.我决定添加volatile,以防优化器在更新中发生变化.

测试了gcc的版本.

$ gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.1.0
Thread model: posix
Run Code Online (Sandbox Code Playgroud)

我没有接受我自己的答案,因为我不是100%确定这对所有编译器都是安全的.编译专家可能会肯定地回答.

如果您需要像释放前那样安全地删除密码,请使用编译器测试此函数并查看原始程序集.您不必了解程序集,只需确保调用___bzero函数(memset)和_free函数.

目前的工作版本:

void free_pword(char * pword) {
    //instead of changing the argument to the function, I added a volatile variable
    //this was I don't have to change the calls to this …
Run Code Online (Sandbox Code Playgroud)

c gcc clang

5
推荐指数
1
解决办法
406
查看次数

标签 统计

c ×2

clang ×1

function ×1

gcc ×1

string ×1