C,子串中的分段错误

时间:2014-04-01 02:52:04

标签: c segmentation-fault

我得到了this question的帮助,其中一个答案提示了这种技术,但我在这段代码中不断收到分段错误(核心转储)错误。

char *nam = array;//<-----(array is a string, we can use "test string" for it
int i = 0;
int length = strlen(array);
int count = 1;
printf("%i [%s]\n", length,nam);    
for(i; i < length; i++)
{
    puts(nam + i);
    nam[strlen(nam) - 1] = '\0';
}

应该发生什么,是我应该用字符串制作金字塔,从正面删除一个字母,从背面删除一个字母。使用此代码,我设法摆脱前面的一个字母,但错误发生在“替换”最后一个字母的'\ 0'。有谁知道为什么会这样?

编辑------------(更新的澄清代码)

void pyramid(char array[])
{    
char nam[] = array;
int i = 0;
int length = strlen(nam);
int count = 1;
printf("%i [%s]\n", length, nam);   
for(i; i < length; i++)
{
    puts(nam + i);
    nam[strlen(nam) - 1] = '\0';
    printf("[%s]\n", nam);
}
}

主要班级

int main (void)
{
    char *name = "TEST STRING";
    pyramid(name);
}

希望这澄清一下 这段代码在char [] = array上给了我一个无效的初始化器;线

3 个答案:

答案 0 :(得分:4)

char *nam = array;//<-----(array is a string, we can use "test string" for it

你不能修改变量name,因为"test string"是在字符常量区域中分配的,所以你不能修改它。

请使用char nam[] = "test string".,在这种情况下,"test string"已在堆栈中分配,因此您可以对其进行修改。

答案 1 :(得分:3)

array是一个字符串文字,您不应该尝试更改它。

更改

char *nam = array;

char nam[] = array;

再试一次。

顺便说一句,实际代码应该看起来像

char name[] = "test string";

更新:

版本1,需要C99 VLA

void pyramid(char array[])
{    
    int length = strlen(array);
    char nam[length+1];
    int i = 0;
    int count = 1;

    strcpy(nam, array);
    printf("%i [%s]\n", length, nam);   
    for(i; i < length; i++)
    {
        puts(nam + i);
        nam[strlen(nam) - 1] = '\0';
        printf("[%s]\n", nam);
    }
}

版本2,使用动态内存分配:

void pyramid(char array[])
{    
    char *nam;
    int i = 0;
    int length = strlen(array);
    int count = 1;

    if ((nam = malloc(length+1)) == NULL) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    strcpy(nam, array);

    printf("%i [%s]\n", length, nam);   
    for(i; i < length; i++)
    {
        puts(nam + i);
        nam[strlen(nam) - 1] = '\0';
        printf("[%s]\n", nam);
    }

    free(nam);
}

答案 2 :(得分:1)

字符串文字存储在只读内存段中。您应该将其视为const char *或不可变字符串。

如果您正在编写一个函数来对字符串执行破坏性操作,那么最好还是复制它。

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

void pyramid_demo(const char *input) {
    /* Copy input to buf */
    int len = strlen(input);
    char *buf = malloc(len + 1);
    strcpy(buf, input);

    puts(buf);
    buf[len - 1] = '\0';    /* Now you can write to buf */
    puts(buf + 1);
}

int main(void) {
    /* The literal string is immutable */
    pyramid_demo("Hello world");
}

pyramid()函数

的批判

除了段错误之外,您的pyramid()功能还存在其他问题:

  • count是未使用的变量。

  • for(i中,i无用。如果您使用的是C99或更新版本,则应删除i的现有声明/初始化,并改为编写:

    for (int i = 0; i < length; i++)
    
  • char nam[] = array;是无意义的别名。它不会复制输入。

  • 避免重复调用strlen(),因为每次调用都需要沿着整个字符串向下查找\0终止符。您已经在开头设置了length,因此只需通过递减length来跟踪字符串长度。