在C中合并字符时出现segfault

evrscar2  于 2023-08-03  发布在  其他
关注(0)|答案(1)|浏览(203)

我在为面试做编码挑战。获取此错误:

  1. Reading symbols from Solution...done.
  2. [New LWP 183007]
  3. Core was generated by `./Solution'.
  4. Program terminated with signal SIGSEGV, Segmentation fault.
  5. #0 0x00007fb1eb4fdcf8 in ?? ()

字符串
守则如下:

  1. #include <assert.h>
  2. #include <ctype.h>
  3. #include <limits.h>
  4. #include <math.h>
  5. #include <stdbool.h>
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. char* readline();
  12. /*
  13. * Complete the 'newPassword' function below.
  14. *
  15. * The function is expected to return a STRING.
  16. * The function accepts following parameters:
  17. * 1. STRING a
  18. * 2. STRING b
  19. */
  20. /*
  21. * To return the string from the function, you should either do static allocation or dynamic allocation
  22. *
  23. * For example,
  24. * char* return_string_using_static_allocation() {
  25. * static char s[] = "static allocation of string";
  26. *
  27. * return s;
  28. * }
  29. *
  30. * char* return_string_using_dynamic_allocation() {
  31. * char* s = malloc(100 * sizeof(char));
  32. *
  33. * s = "dynamic allocation of string";
  34. *
  35. * return s;
  36. * }
  37. *
  38. */
  39. char* newPassword(char* a, char* b) {
  40. int len = strlen(a);
  41. char* c = "";
  42. int i = 0;
  43. for(; i < len; i++){
  44. strcat(c, &a[i]);
  45. strcat(c, &b[i]);
  46. }
  47. for(int z = i; z < strlen(b); z++){
  48. strcat(c, &b[z]);
  49. }
  50. return c;
  51. }
  52. int main()
  53. {
  54. FILE* fptr = fopen(getenv("OUTPUT_PATH"), "w");
  55. char* a = readline();
  56. char* b = readline();
  57. char* result = newPassword(a, b);
  58. fprintf(fptr, "%s\n", result);
  59. fclose(fptr);
  60. return 0;
  61. }
  62. char* readline() {
  63. size_t alloc_length = 1024;
  64. size_t data_length = 0;
  65. char* data = malloc(alloc_length);
  66. while (true) {
  67. char* cursor = data + data_length;
  68. char* line = fgets(cursor, alloc_length - data_length, stdin);
  69. if (!line) {
  70. break;
  71. }
  72. data_length += strlen(cursor);
  73. if (data_length < alloc_length - 1 || data[data_length - 1] == '\n') {
  74. break;
  75. }
  76. alloc_length <<= 1;
  77. data = realloc(data, alloc_length);
  78. if (!data) {
  79. data = '\0';
  80. break;
  81. }
  82. }
  83. if (data[data_length - 1] == '\n') {
  84. data[data_length - 1] = '\0';
  85. data = realloc(data, data_length);
  86. if (!data) {
  87. data = '\0';
  88. }
  89. } else {
  90. data = realloc(data, data_length + 1);
  91. if (!data) {
  92. data = '\0';
  93. } else {
  94. data[data_length] = '\0';
  95. }
  96. }
  97. return data;
  98. }


我不是一个真正的C/C++的人,所以需要一些见解。

o2gm4chl

o2gm4chl1#

第一个循环的边界不正确。如果a的长度比b的长度长,则会存取b结尾以外的字符。你应该有三个循环。
1.第一个循环的次数与两个长度中较小者的次数相同。
1.第二个循环在a超过b的字符上循环。
1.第三个循环在b超过a的字符上循环。
在C语言中,所有的字符串,包括空字符串"",实际上都是字符数组。空字符串是一个由一个字符(空终止符)组成的数组。不允许修改这些数组。任何修改此类数组的尝试都会导致未定义的行为。这就是为什么在使用指向文本字符串的指针时,建议使用const char *
方便地,我们知道新密码的长度将是strlen(a) + strlen(b)个字符。我们把它叫做n。这意味着你需要一个n+1个字符的数组。(+1用于NUL。)使用char c[n+1];不可行,因为您希望数组存在于函数末尾之外(因为您要返回它)。因此,您需要使用char *c = malloc(n+1);
然后是strcat的误用。两个参数都应该是(以NULL结尾)字串。如果aUVW,而bxyz,则您要建置的是UVWxyzVWyzWz,而不是UxVyWz。要添加一个字符,由于您已经有足够的内存(在上面的修复之后),您可以直接将赋值给数组中正确的元素。别忘了用NUL终止它。
记:第二节第一段是Some programmer dude写的。

相关问题