【问题标题】:Reversing a C string function crashes?反转 C 字符串函数崩溃?
【发布时间】:2013-05-12 23:39:18
【问题描述】:

我正在尝试编写一个 C 函数来反转传入的 C 样式字符串(即 char *)并返回反转字符串的 char 指针。但是当我在 VS2012 中运行它时,终端中没有打印任何内容,并且显示“main.exe 已停止工作”消息。

#include <stdio.h>
#include <string.h>
char * rrev_str(char * str )
{
    char *revd_str=""; //I tried char revd_str []="" error: stack around "revd_str" is corrupted
    int i,r;
    int str_len=strlen(str);
    for (i = str_len-1, r=0; i >=0; i--,r++)
    {
        revd_str[r]= str[i];
    }
    return revd_str;
}

int main(int argc, char* argv[])
{
   char str1 [] ="STEETS";
   char str2 [] ="smile everyday!";

   //reverse "chars" in a C string and return it
   char * rev_string=rrev_str(str1);
}

【问题讨论】:

标签: c string return reverse


【解决方案1】:

这里的问题是三个方面。首先,您没有为反转的字符串分配足够的空间,其次,您在 rrev_str() 中返回了一个指向局部变量的指针,第三,您正在修改字符串文字。您需要在堆上为 revd_str 分配空间:

char * rrev_str(char * str )
{   
    int i,r;
    int str_len=strlen(str);

    char *revd_str=malloc(str_len + 1); 
    memset(revd_str, 0, str_len + 1);

    for (i = str_len-1, r=0; i >=0; i--,r++)
    {
        revd_str[r]= str[i];
    }
    return revd_str;
}

【讨论】:

  • 您还需要分配终止符,因为 malloc 不保证零内存位置。
  • 感谢工作。使用 1 个小的语法编辑:memset 的第三个参数需要一个变量,并且在传递时没有对该 var 进行任何其他操作。因此,它需要一个存储此 val 的变量,而不是 str_len+1。所以我把 str_len+1 放在一个 temp_var 中并将它传递给 memset
  • 是的,它会起作用的。但是您需要在不需要时释放堆内存。如果以后不释放它可能是内存泄漏。
【解决方案2】:

问题:

您正在访问无效的内存地址。
revd_str 指向长度为 1 的文字常量字符串,并且您正在访问它超出了无效的长度。

解决方案:

  • 创建所需长度的 char 数组(静态或动态)。
  • 反转给定的字符串。
  • 将第二个参数作为目标字符串传递
    语法:char * rrev_str(char * src, char *dest);

反转给定的字符串

char * rrev_str(char * str )
{
   int start = 0;
   int end = strlen(str) - 1;
   char temp;

    for (; start < end; start++ ,end--)
    {
        temp = str[start];
        str[start] = str[end];
        str[end] = temp;
    }
    return str;
}

int main(int argc, char* argv[])
{
   char string [] ="smile";

   //reverse "chars" in a C string and return it
   char * rev_string = rrev_str(string);

   printf("%s",rev_string);
}


将第二个参数作为目标字符串传递

char * rrev_str(char * src, char *dest)
{
   int srcLength = strlen(src);
   int destLength = strlen(dest);
   int i;
   // Invalid destination string
   if (srcLength > destLength)
   {
        return NULL;
   }

   dest[srcLength] = '\0';
   srcLength--;
    for (i=0; srcLength >= 0;i++, srcLength--)
    {
        dest[i] = src[srcLength];
    }

 return dest;
}

int main(int argc, char* argv[])
{
   char string [] ="smile";
   char revString[20];  

   //reverse "chars" in a C string and return it
   char * rev_string = rrev_str(string, revString);

    printf("%s",rev_string);
}

【讨论】:

    【解决方案3】:

    什么!你在做..

    char *revd_str=""; // Creating String Literal which can't be modified because they are read only  
    char *revd_str[]=""; // Creating Char Array of Size Zero.
    

    所以解决方案是

    要么参考你的字符串

    char *revd_str = strdup(str);
    

    或者创建动态字符数组

    char *revd_str = (char*) malloc (strlen(str)+1);  
    

    您的程序将运行良好。反转逻辑不正确,因此请修改它。下面给出了一个示例解决方案

    char * rrev_str(char * str )
    {
        char *revd_str=strdup(str);
        int i;  // no need for extra 'int r'
        int str_len=strlen(str);
        for (i = 0; i < str_len/2; i++)
        {
            char temp = revd_str[i];
            revd_str[i]= revd_str[str_len - 1 -i];
            revd_str[str_len - 1 -i] = temp;
        }
        return revd_str;
    } 
    

    【讨论】:

    • 或者也许使用strdup 来获得相同大小的副本。此外,char *revd_str=str 不会创建 str 的副本,它会覆盖 str。
    • 感谢您的指出。我被误认为是给定字符串的变化。我已经更正了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-30
    • 1970-01-01
    • 2015-11-03
    • 2020-02-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    相关资源
    最近更新 更多