寻求帮助以识别C函数中的内存泄漏

wz1wpwve  于 2023-10-16  发布在  其他
关注(0)|答案(1)|浏览(149)

我目前正在尝试在C中实现setenv函数,该函数设置环境变量的值,我担心由于strdup而导致Valgrind标记的代码中的内存泄漏。我非常感谢您的见解,帮助我识别以下代码中的任何内存泄漏问题:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. extern char **environ;
  6. int _setenv(const char *name, const char *value)
  7. {
  8. char **new_environ, *current_env, *env_name;
  9. int count = 0, modified = 0, i = 0;
  10. /* Count the number of environment strings */
  11. while (environ[i])
  12. {
  13. count++;
  14. i++;
  15. }
  16. /* Create a copy of the environment variable */
  17. new_environ = malloc(sizeof(char *) * (count + 2));
  18. if (!new_environ)
  19. {
  20. perror("Memory Allocation Error");
  21. return (-1);
  22. }
  23. for (i = 0; i < count; i++)
  24. {
  25. current_env = strdup(environ[i]);
  26. env_name = strtok(current_env, "=");
  27. if (env_name != NULL && strcmp(env_name, name) == 0)
  28. {
  29. new_environ[count] = malloc(strlen(name) + strlen(value) + 2);
  30. if (new_environ[count])
  31. {
  32. sprintf(new_environ[count], "%s=%s", name, value);
  33. new_environ[count + 1] = NULL; /* Terminate the new array */
  34. modified = 0;
  35. free(current_env);
  36. break;
  37. }
  38. }
  39. else
  40. {
  41. new_environ[i] = current_env;
  42. modified = 1;
  43. free(current_env);
  44. }
  45. }
  46. if (!modified)
  47. {
  48. new_environ[count] = malloc(strlen(name) + strlen(value) + 2);
  49. if (new_environ[count])
  50. {
  51. sprintf(new_environ[count], "%s=%s", name, value);
  52. new_environ[count + 1] = NULL; /* Terminate the new array */
  53. }
  54. }
  55. else
  56. {
  57. new_environ[count] = NULL; /* Terminate the new array */
  58. }
  59. environ = new_environ;
  60. return (0);
  61. }
yws3nbqq

yws3nbqq1#

  1. if (new_environ[count])
  2. { ... }
  3. else
  4. {
  5. // this will be regarded as a leak of current_env
  6. }

更好的设计应该是:

  1. current_env = strdup(environ[i]);
  2. env_name = strtok(current_env, "=");
  3. bool modified = alloc_name(current_env, env_name);
  4. if(modified)
  5. { /* ... */ }
  6. else
  7. { /* ... */ }
  8. free(current_env); // always free it, unconditionally.

我也不明白这一部分:

  1. new_environ[i] = current_env;
  2. modified = 1;
  3. free(current_env);

new_environ[i] = current_env是一个 * 软拷贝 *,只将指针分配给指针数组。实际数据仍在原处。因此,如果你free(current_env),那么new_environ[i]最终指向垃圾,因为你刚刚释放了它指向的数据。

展开查看全部

相关问题