在 C 中创建一个 StartsWith 函数得到 "Segmentation fault",有什么问题吗?
Make a StartsWith function in C getting "Segmentation fault", What's wrong?
我正在尝试制作一个 startswith
函数,如果我有一个字符串包含
"Hello I am kira"
会拆分成第一个字
"Hello"
仅
而且我真的尽了最大努力把它弄成这个形式
#include <stdio.h>
unsigned char *startswith(unsigned char *str)
{
char *result;
char *cstr = (char *)str;
for (int i=0; cstr[i] != ' '; i++)
result[i] = cstr[i];
return(result);
}
int main()
{
printf("%s\n",startswith("What is your name momo?"));
return 0;
}
应该打印 "in my imagination"
What
和 newline
然后用 0
退出
但是我在编译时遇到了未知的神圣错误
Segmentation fault
我不明白为什么会这样,甚至无法定位问题所在
gcc
没有帮助或显示警告
stdio.h
header 只是打印结果而已
我知道有一种方法可以在不使用任何标准库的情况下实现这一点,但我需要 leading
谢谢!
在 result
中分配一些内存。
result=malloc(sizeof(char)*MAXLEN);
现在您正在访问存储在 result
中的一些垃圾值。
访问未初始化的变量是Undefined Behavior
。
你也可以分配strlen(str)+1
因为你知道不管结果是什么最多只要str
.
$7.20.3.1 另一点是,您可以使用 calloc
函数,其中 space 被初始化为所有位 zero.This 的好处是始终有一个空终止字符串,即使您不小心省略了空终止1
1.由 David C. Rankin 指出
基本上你在这里做的是使用一个没有分配内存的指针。你需要使用 malloc 为结果变量分配内存,为此你需要包括 stdlib.h
#include <stdio.h>
#include<stdlib.h>
#define MAXLEN 1000
unsigned char *startswith(unsigned char *str)
{
char *result = malloc(sizeof(char)*MAXLEN);
char *cstr = (char *)str;
for (int i=0; cstr[i] != ' '; i++)
result[i] = cstr[i];
return(result);
}
int main()
{
printf("%s\n",startswith("What is your name momo?"));
return 0;
}
对这里发生的事情进行更深入的解释...您遇到了段错误,因为您正在取消引用指向您的进程不拥有的内存的指针。您的 char* result
指针未初始化,这意味着它可能包含任何类型的垃圾数据。当您尝试 result[i] = cstr[i]
时,您正在调用 undefined behavior(所以不会再让我 link 他们未定义的行为文档),这仅仅意味着从这一点开始程序的向前执行具有不可预测的结果。在您的情况下,UB 表现为段错误,尽管它可能并非总是如此。
为了初始化您的指针,您必须使用 malloc
或其类似函数之一为其分配一些 space。当你用完它时,你还应该 free
你的记忆。你的程序太短了,在这种情况下这没什么大不了的(OS 肯定会在进程退出时清理分配给进程的所有内存),但养成习惯是件好事。
#include <stdio.h>
#include <string.h>
// this function shouldn't modify str (and in fact modifying a string
// literal like you're passing in would be UB anyway), so make this
// a const char*
char *startswith(const char *str)
{
// sizeof(char) is defined as 1 in the standard, so you can leave it out of the malloc expression
char *result = malloc(strlen(str)+1); // Assuming str has at least 1 space, this will guarantee enough space for result
if (result == NULL) // make sure malloc returned some memory for you
{
// handle the error here how you want
fprintf(stderr, "out of memory!\n");
exit(-1);
}
// no need for cstr
int i; // move i out of the loop so it will be in scope after the loop
for (i=0; str[i] != ' '; i++)
result[i] = str[i];
// NUL terminate your string
result[i] = '[=10=]';
// "return" isn't a function, parenthesis unnecessary.
return result;
}
int main(void)
{
// store the returned result to a variable so we can free it
char* result = startswith("What is your name momo?");
printf("%s\n", result);
// clean up the memory
free(result);
return 0;
}
我正在尝试制作一个 startswith
函数,如果我有一个字符串包含
"Hello I am kira"
会拆分成第一个字
"Hello"
仅
而且我真的尽了最大努力把它弄成这个形式
#include <stdio.h>
unsigned char *startswith(unsigned char *str)
{
char *result;
char *cstr = (char *)str;
for (int i=0; cstr[i] != ' '; i++)
result[i] = cstr[i];
return(result);
}
int main()
{
printf("%s\n",startswith("What is your name momo?"));
return 0;
}
应该打印 "in my imagination"
What
和 newline
然后用 0
退出
但是我在编译时遇到了未知的神圣错误
Segmentation fault
我不明白为什么会这样,甚至无法定位问题所在
gcc
没有帮助或显示警告
stdio.h
header 只是打印结果而已
我知道有一种方法可以在不使用任何标准库的情况下实现这一点,但我需要 leading
谢谢!
在 result
中分配一些内存。
result=malloc(sizeof(char)*MAXLEN);
现在您正在访问存储在 result
中的一些垃圾值。
访问未初始化的变量是Undefined Behavior
。
你也可以分配
strlen(str)+1
因为你知道不管结果是什么最多只要str
.$7.20.3.1 另一点是,您可以使用
calloc
函数,其中 space 被初始化为所有位 zero.This 的好处是始终有一个空终止字符串,即使您不小心省略了空终止1
1.由 David C. Rankin 指出
基本上你在这里做的是使用一个没有分配内存的指针。你需要使用 malloc 为结果变量分配内存,为此你需要包括 stdlib.h
#include <stdio.h>
#include<stdlib.h>
#define MAXLEN 1000
unsigned char *startswith(unsigned char *str)
{
char *result = malloc(sizeof(char)*MAXLEN);
char *cstr = (char *)str;
for (int i=0; cstr[i] != ' '; i++)
result[i] = cstr[i];
return(result);
}
int main()
{
printf("%s\n",startswith("What is your name momo?"));
return 0;
}
对这里发生的事情进行更深入的解释...您遇到了段错误,因为您正在取消引用指向您的进程不拥有的内存的指针。您的 char* result
指针未初始化,这意味着它可能包含任何类型的垃圾数据。当您尝试 result[i] = cstr[i]
时,您正在调用 undefined behavior(所以不会再让我 link 他们未定义的行为文档),这仅仅意味着从这一点开始程序的向前执行具有不可预测的结果。在您的情况下,UB 表现为段错误,尽管它可能并非总是如此。
为了初始化您的指针,您必须使用 malloc
或其类似函数之一为其分配一些 space。当你用完它时,你还应该 free
你的记忆。你的程序太短了,在这种情况下这没什么大不了的(OS 肯定会在进程退出时清理分配给进程的所有内存),但养成习惯是件好事。
#include <stdio.h>
#include <string.h>
// this function shouldn't modify str (and in fact modifying a string
// literal like you're passing in would be UB anyway), so make this
// a const char*
char *startswith(const char *str)
{
// sizeof(char) is defined as 1 in the standard, so you can leave it out of the malloc expression
char *result = malloc(strlen(str)+1); // Assuming str has at least 1 space, this will guarantee enough space for result
if (result == NULL) // make sure malloc returned some memory for you
{
// handle the error here how you want
fprintf(stderr, "out of memory!\n");
exit(-1);
}
// no need for cstr
int i; // move i out of the loop so it will be in scope after the loop
for (i=0; str[i] != ' '; i++)
result[i] = str[i];
// NUL terminate your string
result[i] = '[=10=]';
// "return" isn't a function, parenthesis unnecessary.
return result;
}
int main(void)
{
// store the returned result to a variable so we can free it
char* result = startswith("What is your name momo?");
printf("%s\n", result);
// clean up the memory
free(result);
return 0;
}