交换两个字符串时访问正确的内存时遇到分段错误

在交换操作之前,我编写了一个交换函数来交换cpp中的两个c'style字符串。

我可以正确标注二维字符串s [2] [27]的第一行,但是我将s [0]替换为s [1],我尝试了s [0],编译器给了我一个提示。分割错误。

void swap1(char *a,char *b)
{
    char *temp;
    int i = 0,j = 0;
    while (a[i] != '\0')
    {
        temp[j] = a[i];
        i++;
        j++;
    }
    temp[j] = '\0';
    i = 0,j = 0;
    while (b[i] != '\0')
    {
        a[j] = b[i];
        i++,j++;
    }
    a[j] = '\0';
    i = 0,j = 0;
    while (temp[i] != '\0')
    {
        b[j] = temp[i];
        i++,j++;
    }
    b[j] = '\0';
}
int main()
{
    char s[2][27] = {"wangzhehan","cuisibo"};
    // const char s[2][10]={"111","222"};
    cout << s[0] << endl;//s[0] can be printed correctly

    swap1(s[0],s[1]);

    cout << s[0];//the compiler showed a segmentation fault here

预期结果是 王哲涵 翠波 但实际上结果是 王哲涵

然后编译器显示“发生了异常。 分段故障” 或者,有没有更好的方法而不使用标准库函数来交换两个字符串?

raners 回答:交换两个字符串时访问正确的内存时遇到分段错误

代码:

   char *temp;
[...]
        temp[j] = a[i];

a[i]存储到当前堆栈上的任何地址(了解未分配的内存)。这会崩溃。如果您需要将某些内容交换到临时文件,请先将您的临时文件分配为最小字符串长度的大小。

请注意,您的代码不是一个好主意。

函数签名需要两个指向char数组的指针。它没有说什么是数组长度。如果字符串长度不同,则不能安全地交换字符串(因为第二个参数的数组大小可以小于第一个参数的数组大小)。

如果您真的想要重新发明轮子,则可以执行以下操作:

void swap(char *& s1,char *& s2) { char * tmp = s2; s2 = s1; s1 = tmp; }
int main()
{
    char * s[2] = {"wangzhehan","cuisibo"};
    cout << s[0] << endl;//s[0] can be printed correctly

    swap(s[0],s[1]);

    cout << s[0];
,

交换两个字符串时,您不需要整体存储临时字符串。
(否则您将不得不依靠动态分配)

在您的代码中声明char *temp;并在使用temp[j]之后立即声明,但未分配此临时字符串(指针指向任何东西)。

我不会在此处提供完整的解决方案,因为它看起来像是一种练习,但仅 这个建议。
使用单个循环,将a[i]放置在临时char(而不是char *)中, 然后将b[i]移至a[i],最后将临时char移至b[i]
(交换字符时,您必须注意两个字符串的长度)

,

您没有在要临时复制字符串的位置分配内存。指针temp未初始化。

char *temp;

因此该函数调用未定义的行为。

如果使用标准的C字符串函数,则该函数可以编写得更简单。

例如

#include <iostream>
#include <cstring>
#include <algorithm>

void swap1( char *a,char *b )
{
    size_t n = std::max( strlen( a ),strlen( b ) ) + 1;

    char *temp = new char[n];

    std::strcpy( temp,a );
    std::strcpy( a,b );
    std::strcpy( b,temp );

    delete [] temp;
}    

int main() 
{
    char s[2][27] = {"wangzhehan","cuisibo"};

    std::cout << s[0] << '\n';

    swap1( s[0],s[1] );

    std::cout << s[0] << '\n';

   return 0;
}

程序输出为

wangzhehan
cuisibo

如果不允许使用标准字符串函数,而只能使用循环,则该函数可以采用以下演示程序中所示的以下方式。

#include <iostream>

void swap1( char *a,char *b )
{
    size_t n1 = 0;

    while( a[n1] != '\0' ) ++n1;

    size_t n2 = 0;

    while ( b[n2] != '\0' ) ++n2;

    size_t n = n1 < n2 ? n2 : n1;

    char *temp = new char[n + 1];

    for ( size_t i = 0; ( temp[i] = a[i] ) != '\0'; ++i );
    for ( size_t i = 0; ( a[i] = b[i] ) != '\0'; ++i );
    for ( size_t i = 0; ( b[i] = temp[i] ) != '\0'; ++i );

    delete [] temp;
}    

int main() 
{
    char s[2][27] = {"wangzhehan",s[1] );

    std::cout << s[0] << '\n';

   return 0;
}

函数输出再次是

wangzhehan
cuisibo

最后,最简单的方法是将函数声明为模板函数。在这种情况下,您无需动态分配内存。

例如

#include <iostream>

template <size_t N>
void swap1( char ( &a )[N],char ( &b )[N] )
{
    char temp[N];

    for ( size_t i = 0; ( temp[i] = a[i] ) != '\0'; ++i );
    for ( size_t i = 0; ( a[i] = b[i] )    != '\0'; ++i );
    for ( size_t i = 0; ( b[i] = temp[i] ) != '\0'; ++i );
}    

int main() 
{
    char s[2][27] = {"wangzhehan",s[1] );

    std::cout << s[0] << '\n';

   return 0;
}
本文链接:https://www.f2er.com/3137828.html

大家都在问