以下代码中的分段错误(核心转储)。怎么了?

时间:2014-08-11 17:41:55

标签: c segmentation-fault

我对C比较陌生。我遇到了很多分段错误,但我能在几分钟内找到错误。不过这个让我感到困惑。这是我试图写的一个新功能。这基本上是python代码的C等价物

    r=t[M:N]

这是我的带有测试用例的C代码

    #include <stdio.h>

    char* subarraym(char* a, int M, int N)
    {
    char* s;
    int i;
    for (i=M; i<N; i++){ s[i-M]=a[i]; }
    return s;
    }

   main()
   {
   char* t="Aldehydes and Ketones";
   char* r=subarraym(t,2,10);
   printf("%c\n",r[4]);
   return 0;
   }

预期答案是'd'。但是我遇到了分段错误。 额外信息:我使用的是GCC

3 个答案:

答案 0 :(得分:1)

您的代码无效,因为您的子数组指针从未初始化。你可以复制子阵列,但是你必须管理内存,这对你的问题来说太过分了。

在C中,数组通常作为指针对和元素数传递。例如:

void do_something(char *p, int np);

如果你遵循这个习惯用法,那么假设没有溢出,获得一个子数组是微不足道的:

void do_something_sub(char *p, int np, int m, int n)
{
    do_array(p + m, n);
}

检查和管理溢出也很容易,但它仍然是读者的练习。

注1 :通常,您不会编写do_something_sub()之类的函数,只需使用正确的参数直接调用do_something()

注意2 :有些人更喜欢使用size_t代替int来表示数组大小。 size_t是无符号类型,因此您永远不会有负值。

注3 :在C中,字符串就像char数组一样,但长度是通过用NUL字符结尾来确定的,而不是传递长度。因此,要获取NUL终止的子字符串,您必须将子字符串复制到另一个char数组或修改原始字符串并使用NUL覆盖倒数第二个字符串。

答案 1 :(得分:0)

来自

...,10);

您希望收到10 char(+1 0 - 终结符),因此请以某种方式将其提供给该函数。

不这样做,而是通过

写入无效内存
char * s; /* note, that s is NOT initialised, so it points "nowhere". */
...
  s[i-M] = ...

引发未定义的行为。

在这个答案中可以找到为这种情况提供记忆的可能解决方案:https://stackoverflow.com/a/25230722/694576

答案 2 :(得分:0)

您需要确保必要的记忆。

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

char* subarraym(char *a, int M, int N){
    if(N < 0){
        N += strlen(a);
        if(N < 0)
            N = 0;
    }
    int len = N - M;
    char *s =calloc(len+1, sizeof(char));//memory allocate for substring
    return memcpy(s, &a[M], len);
}

int main(){
    char *t="Aldehydes and Ketones";
    char *r=subarraym(t,2,10);
    printf("%c\n",r[4]);
    free(r);
    return 0;
}