分段错误:11 in C

泰科尔兹

我正在用C编写一个程序,该程序用字符串替换char *中名为“ template”的数字,但是我不断遇到Segmentation Fault:11错误。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

char *rep_str(const char *s, const char *old, const char *new1){
    char *ret;
    int i, count = 0;
    int newlen = strlen(new1);
    int oldlen = strlen(old);

    for (i = 0; s[i] != '\0'; i++){
        if (strstr(&s[i], old) == &s[i]){
            count++;
            i += oldlen - 1;
        }
    }
    ret = (char*)malloc(i + count * (newlen - oldlen));
    if (ret == NULL)
        exit(EXIT_FAILURE);
    i = 0;
    while (*s){
        if (strstr(s, old) == s){ //compare the substring with the newstring
            strcpy(&ret[i], new1);
            i += newlen; //adding newlength to the new string
            s += oldlen;//adding the same old length the old string
        } else {
        ret[i++] = *s++;
        }
    }
    ret[i] = '\0';

    return ret;
}

char* madlib_by_numbers(char* temp, int word_count, char* words[]){
    char* numbers[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
    int tempSize = strlen(temp);

    for (int i = 0; i < tempSize; i++){
        if (isdigit(temp[i])){
            for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
                temp = rep_str(temp, numbers[j], words[j]); //it makes it to this line, but never gets to assert()
            }
        }
    }

    return temp;
}

int main() {
  char* temp1 = "The 1 0 likes to 2 in the moonlight.";
  char* words[] = {"git", "brilliant", "swim"};
  char* result = "The brilliant git likes to swim in the moonlight.";
  int stringLength = strlen(result);

  char* test = madlib_by_numbers(temp1, 3, words);
  assert(strncmp(test, result, stringLength) == 0);
  free(test);

  return 0;
}

当我运行调试器时,它只是说: Segmentation Fault: 11

我仅想了解的是分段错误错误的来源,我怀疑我的循环之一运行了太多次。

自闭症
ret = (char*)malloc(i + count * (newlen - oldlen));

这行代码存在一些问题。

  • 首先,请不要强制转换malloc(或void *您要分配给不同指针类型的变量的malloc,反之亦然)。
  • 如果您打算分配空间来存储字符串,那么终止字符串的位置'\0'在哪里?您需要意识到,对于一个空old字符串,这将是malloc(0)并且零字节不足以存储一个空字符串。
  • 如果您希望该old字符串可能是的子字符串,那么也会有一个问题new(例如,您要替换"0""hell0")。您需要调整算法以解决此问题。我会把它留给您尝试的挑战:)

for (int i = 0; i < tempSize; i++){
    if (isdigit(temp[i])){
        for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
            temp = rep_str(temp, numbers[j], words[j]); //it makes it to this line, but never gets to assert()
        }
    }
}

用户先前的答案正确地突出显示了此代码,但原因不正确...因此他/她提出的解决方案是错误的。

isdigit(temp[i])可能还会对某些输入造成段错误。isdigit((unsigned char) temp[i])在这种情况下,我建议使用代替。

words[j]word_count3j大于或等于3的位置访问无效的您正在访问该数组的边界。

您还需要注意您的free所有内存*alloc(同时不要free占用您没有的内存*alloc)。忘记做前者不会导致崩溃,但是您的程序不会快乐地运行。它会使用内存

考虑这样的事情,而不是:

temp = strdup(temp);
if (temp == NULL) {
    exit(EXIT_FAILURE);
}
for (int i = 0; i < tempSize; i++){
    if (isdigit((unsigned char) temp[i])){
        for (int i = min(word_count, sizeof(numbers) / sizeof(char*)), j = 0; j < i; j++){
            char *new = rep_str(temp, numbers[j], words[j]);
            free(temp);
            temp = new;
        }
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章