分段当我在函数中的数组中分配值时出错

时间:2015-02-15 16:44:41

标签: c arrays segmentation-fault malloc

我调试了程序,当我执行[k] = a [h]时,分段错误确实出现了。 数组a是一个dinamic数组,所以我无法理解问题出在哪里...... 你能救我吗?

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

void Invert(char* a, int k, int h) {
    if(k < h) {
        char app;
        app = a[k];
        a[k] = a[h]; //here is the error
        a[h] = app;
        Invert(a,k+1,h-1);
        }
}

void CallInvert(char* a, char k) {
    int n = strlen(a);
    Invert(a, k, n-1);
}


int main(int argc, char *argv[]) {
    char *a; int k,i;
    a = malloc(sizeof(char)*sizeof("Hi, how are you?"));
    a = "Hi, how are you?";
    k = 5;
    if(k>=strlen(a)) {
        printf("ERROR");
        return 0;
    }
    printf("Before: \"%s\"\n", a);
    CallInvert(a,k);
    printf("After: \"%s\"\n",a);
    free(a);
    return 0;
}

5 个答案:

答案 0 :(得分:2)

在main()中,a = "Hi, how are you?"是错误的。您在此处指定一个指向常量字符串的指针。稍后,当您尝试写入常量字符串时,它将崩溃(正如iharob在下面指出的那样,写入一个更具体的常量字符串,称为导致'未定义的行为';这恰好是您平台中的分段错误)。

答案 1 :(得分:0)

您需要使用strcpy功能。喜欢:

a = malloc(sizeof(char)*sizeof("Hi, how are you?"));
    strcpy(a ,"Hi, how are you?");

SEGFAULT是因为您无法更改值constat literal。

答案 2 :(得分:0)

请参阅我对代码内容的更改以进行内存分配:

    a = (char*)malloc(sizeof(char)* (sizeof("Hi, how are you?") + 1) );
    strcpy(a,"Hi, how are you?");

sizeof("Hi, how are you?")正常工作,但要存储'\0'(字符串结尾),您还需要一个字符。当然,strcpystrncpy用于将字符复制到可修改的内存中。

答案 3 :(得分:0)

我尝试了多次执行并且没有在上面提到的行中找到问题,现在我的代码看起来像这样:

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

void Invert(char* a, int k, int h) {
    if (k < h) {
        char app;
        app = a[k];
        a[k] = a[h];
        a[h] = app;
        Invert(a, k + 1, h - 1);
    }
}

void CallInvert(char* a, char k) {
    int n = strlen(a);
    Invert(a, k, n - 1);
}

int main(int argc, char *argv[]) {
    char *a = NULL; 
    int k;
    a = (char *)malloc(sizeof(char)*strlen("Hi, how are you?") + 1);
    strcpy(a, "Hi, how are you?");
    k = 5;
    if (k >= strlen(a)) {
        printf("ERROR");
        return 0;
    }
    printf("Before: \"%s\"\n", a);
    CallInvert(a, k);
    printf("After: \"%s\"\n", a);
    free(a);
    return 0;
}

似乎工作正常并产生了输出:

  

之前:“嗨,你好吗?”

     

之后:“嗨,嗨,我的时代了”

以下是我所做的一些更改:

  1. 使用strlen获取字符串的长度,使用strcpy来复制字符串,但我发现它有 已经在评论中被捕获,为了清楚起见,我将它留在这里。
  2. 类似于Visual Studio,将malloc的返回值转换为char * 投掷错误。这实际上取决于你是什么平台 跑来跑去。

答案 4 :(得分:0)

您的问题是通过为指针指定字符串文字而产生的,这会覆盖malloc返回的地址。这也意味着您对free的调用将触发未定义的行为,例如段错误,因为您实际上是这样做的:

char *a;
a = "Hi, how are you?";
free (a);

您也无法释放malloc返回指针的内存。这意味着您有内存泄漏。

正如其他人所说,您希望使用strcpy复制字符串:

a = malloc (sizeof "Hi, how are you?");
strcpy (a, "Hi, how are you?");

然后事情应该正常。

在此上下文中忽略不知道如何使用sizeof的人。到目前为止,他们可能不知道字符串文字被认为是一个字符数组,加上一个额外的字符插槽用于空终止符,而不仅仅是指向这种数组的指针。如果您愿意,可以使用strlen并为其添加1,但是当您嵌入空字符时,这会失败,与sizeof运算符不同:

#define HELLO "Hello\0World!"
printf (
    "%zu\n%zu\n",
    sizeof HELLO,
    strlen (HELLO) + 1
);

另外,我只是不喜欢调用一个函数并执行算术,而编译器可以在没有这个开销的情况下为我做这个。

但是,一旦将字符串文字分配给指针,就会删除任何大小信息,这可能是对sizeof和字符串文字的误解来自的地方。在这种情况下,使用strlen更安全。公平地说,我不知道任何代码实际上将空字符嵌入到作为sizeof运算符的操作数的字符串文字中。