为什么代码会出现segmentation fault?有时它不会发生

why does the code occur segmentation fault? sometimes it not occur

我想将句子中的 space 替换为“%20”。 例如:

Input:"How are you?"
Output:"How%20are%20you?"

而且我在短句中成功做到了,但是当我使用 20+ space 时。 例如:

Input:"                    "
Output: segementation falut

希望能找到原因,谢谢大家。 这是我在 C:

中的代码
char* replaceSpace(char* s ) {
    // write code here
    int len = strlen(s);//to mark the length of s
    for(int i = 0; i < len; i++)
    {
        
        if(s[i] == 32)
        {
            len = len + 2;
            for(int j = 0; j < len-i-1; j++){
                s[len-j] = s[len-j-2]; 
            }
            s[i] = '%';
            s[i+1] = '2';
            s[i+2] = '0';
        }
    }
    return s;
}

非常感谢。

你不能像那样动态增加长度。您正在访问 s 之外的 un-allocated 索引,同时引用它,因此导致段错误。

当您尝试访问内存的未分配部分时,通常会发生分段错误。

此问题的可能解决方法是创建一个新字符串并正常复制所有字符(space 除外)。对于您遇到的每个 space 字符,您将其替换为“%20”。因此新字符串的长度将是它包含的 space 的三倍加上其余字符(如果有的话)。

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


// Construct an ADT called String
typedef struct {
  char *str;
  size_t length;
  size_t str_size;
} String;


// Initialize our ADT
String *initStr(void);
// Free the memory allocated for `String`
void destroyStr(String *);
// Get input from `stdin`
String *input(char *);
// Count the total number of given
// character in the string
size_t count(String *, char);
// Replace each spaces in the string
// with its hex value
String *convert(String *);


int main(void)
{
    String *s = input("Input: ");
    s = convert(s);
    printf("Output: %s\n", s->str);
    
    destroyStr(s);
    return 0;
}


String *initStr(void)
{
  String *s = malloc(sizeof(String));
  s->str = malloc(sizeof(char));
  s->str[0] = '[=10=]';
  s->length = 0;
  s->str_size = 1;
  return s;
}


String *input(char *label)
{
  printf("%s", label);
  String *s = initStr();
  
  int c;
  while ((c = getc(stdin)) != '\n' && c != EOF) {
    // Dynamically allocate string. If the string
    // length is equal to the internal size, allocate
    // twice as of current length.
    if (s->length + 1 == s->str_size) {
      size_t ssize = s->str_size;
      s->str = realloc(
        s->str, 2 * ssize * sizeof(char)
      );
      
      if (s->str == NULL)
        return NULL;
      
      s->str_size = 2 * ssize;
    }
    s->str[s->length++] = c;
  }
  
  s->str[s->length] = '[=10=]';
  return s;
}


void destroyStr(String *s)
{
  free(s->str);
  free(s);
}


size_t count(String *s, char c)
{
  size_t count = 0;
  for (size_t i = 0; i < s->length; ++i)
    if (s->str[i] == c)
      ++count;
  return count;
}


String *convert(String *old_s)
{
  size_t total_spaces = count(old_s, ' ');
  
  // Return the original string if there are
  // no spaces in it
  if (total_spaces == 0)
    return old_s;
  
  // The new string will contain thrice as many characters
  // for each space plus the other characters
  size_t new_s_len = (
    3 * total_spaces + 
    old_s->length - total_spaces
  );
  
  String *new_s = initStr();
  new_s->str = malloc( (new_s_len + 1) * sizeof(char) );
  new_s->str_size = new_s_len + 1;
  
  for (size_t i = 0; i < old_s->length; ++i) {
    if (old_s->str[i] == ' ') {
      new_s->str[new_s->length++] = '%';
      new_s->str[new_s->length++] = '2';
      new_s->str[new_s->length++] = '0';
    }
    else
      new_s->str[new_s->length++] = old_s->str[i];
  }
  
  new_s->str[new_s->length] = '[=10=]';
  destroyStr(old_s);
  return new_s;
}

由于 C 没有任何 built-in String 数据类型,我们尝试使用 struct 和字符数组来模拟数据类型。我们还必须自己处理内存管理。这可能会变得很麻烦,并且通常与实际问题没有那么密切的关系。因此,我建议您转向 C++ 或 Rust。