【问题标题】:Segmentation fault when copying string to将字符串复制到时出现分段错误
【发布时间】:2013-12-06 16:00:35
【问题描述】:

去那里!

下面是我今天做的一个小程序。它需要一个字符串表,在没有反转表的情况下反转所有字符串,然后对这些反转的字符串进行排序,然后将它们反转回来,最后打印整个表。

我一直想弄清楚为什么我不能将“slowo”字符串复制到 strcmp 中指向的表中,但没有成功。如果有人能在这种情况下找到解决分段错误的方法,我会很高兴,但我真的想保留下面的方法。

感谢您的帮助! :)

编辑通过使用调试器,我确定分段错误出现在 strcpy 中,如果不清楚的话......

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

const int ROZMIAR=4;
char* nieposortowane[]={"basia", "zosia", "ala", "genowefa"};

int porownaj(char* a, char* b)
{
return strcmp(a,b);
}

void sortowanie(char** tablica, int N)
{
int zamienione, i;
char tmp;

do
{
    zamienione=0; 
    for(i=0;i<N-1;i++)
        if(porownaj(nieposortowane[i], nieposortowane[i+1])>0)
        {

            tmp=**(tablica+i);
            **(tablica+i)=**(tablica+(i+1));
            **(tablica+(i+1))=tmp;

            zamienione=1;
        }
}
while(zamienione);
}

void wypisz(char** tablica, int N)
{
int i=0;
for(i=0;i<N;i++)
    printf("%s\n", *(tablica+i));
}

void odwr(char** tablica, int N)
{
int i, ln, c;
int start, koniec;
char temp;

for(i=0;i<N;i++)
{
    ln = strlen(tablica[i]);
    char slowo[ln];
    strcpy(slowo,*(tablica+i));
    start=0;
    koniec=ln-1;
    for(c=0;c<(ln/2);c++)
    {
        temp =slowo[start];
        slowo[start]=slowo[koniec];
        slowo[koniec]=temp;
        start++;
        koniec--;
    }
    strcpy(*(tablica+i), slowo);
}
}

int main()
{
printf("Przed sortowaniem: \n");
wypisz(nieposortowane, ROZMIAR);

odwr(nieposortowane, ROZMIAR);
sortowanie(nieposortowane, ROZMIAR);
odwr(nieposortowane, ROZMIAR);

printf("Po sortowaniu babelkowym: \n");
wypisz(nieposortowane, ROZMIAR);

return 0;
}

【问题讨论】:

  • "basia" 是字符串文字。字符串文字重写禁令。

标签: c pointers gcc fault strcpy


【解决方案1】:

分配slowo时,在计算要分配的大小时,应将strlen的结果加1。这是为了容纳终止空字符,它不包含在字符串的长度中(由strlen返回),但必须包含在其分配的总大小中。

【讨论】:

  • 如果这是个问题,我会觉得很愚蠢。虽然我通过将 1 添加到 ln 来固定分配,但运行此程序仍然会出现 Segmentation Fault...
  • 那是因为 BLUEPIXY 是正确的:你不能写信给string literal! PS:波兰语?
【解决方案2】:

AFAICS,您正在尝试修改以下字符串:

char* nieposortowane[]={"basia", "zosia", "ala", "genowefa"};

这些是存储在只读内存中的字符串文字;任何修改它们的尝试(例如,通过反转它们)都将失败。

我使用您的原始代码重现了崩溃。此版本的代码不会崩溃;它会在您的排序代码中进入无限循环。我还没有调试过你的那部分代码。

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

const int ROZMIAR=4;
char basia[] = "basia";
char zosia[] = "zosia";
char ala[] = "ala";
char genowefa[] = "genowefa";
char* nieposortowane[]={basia, zosia, ala, genowefa};

int porownaj(char* a, char* b)
{
return strcmp(a,b);
}

void sortowanie(char** tablica, int N)
{
int zamienione, i;
char tmp;

do
{
    zamienione=0; 
    for(i=0;i<N-1;i++)
        if(porownaj(nieposortowane[i], nieposortowane[i+1])>0)
        {

            tmp=**(tablica+i);
            **(tablica+i)=**(tablica+(i+1));
            **(tablica+(i+1))=tmp;

            zamienione=1;
        }
}
while(zamienione);
}

void wypisz(char** tablica, int N)
{
int i=0;
for(i=0;i<N;i++)
    printf("%s\n", *(tablica+i));
}

void odwr(char** tablica, int N)
{
int i, ln, c;
int start, koniec;
char temp;

for(i=0;i<N;i++)
{
    ln = strlen(tablica[i]);
    char slowo[ln];
    strcpy(slowo,*(tablica+i));
    start=0;
    koniec=ln-1;
    for(c=0;c<(ln/2);c++)
    {
        temp =slowo[start];
        slowo[start]=slowo[koniec];
        slowo[koniec]=temp;
        start++;
        koniec--;
    }
    strcpy(*(tablica+i), slowo);
}
}

int main()
{
printf("Przed sortowaniem: \n");
wypisz(nieposortowane, ROZMIAR);

odwr(nieposortowane, ROZMIAR);
wypisz(nieposortowane, ROZMIAR);

sortowanie(nieposortowane, ROZMIAR);
wypisz(nieposortowane, ROZMIAR);
odwr(nieposortowane, ROZMIAR);
wypisz(nieposortowane, ROZMIAR);

printf("Po sortowaniu babelkowym: \n");
wypisz(nieposortowane, ROZMIAR);

return 0;
}

示例输出:

Przed sortowaniem: 
basia
zosia
ala
genowefa
aisab
aisoz
ala
afewoneg

在那之后我不得不打断,但你可以看到字符串反转成功。

您需要找出一个更通用的解决方案;对于一个小的固定集合来说,像我一样命名单个数组很容易,但通常不是这样。一种可能性是使用strdup() 将每个字符串复制到分配的空间中:

enum { SIZE_NPSW = sizeof(nieposortowane) / sizeof(nieposortowane[0] };

for (i = 0; i < SIZE_NPSW; i++)
    nieposortowane[i] = strdup(nieposortowane[i]);

【讨论】:

  • 是的!这解决了问题。由于全局声明的更改,我不得不稍微更改冒泡排序功能,但它现在可以工作了。谢谢你:)
猜你喜欢
  • 2012-06-17
  • 2021-12-20
  • 2021-01-25
  • 2014-11-01
  • 1970-01-01
  • 2017-08-01
  • 1970-01-01
  • 2013-08-31
  • 1970-01-01
相关资源
最近更新 更多