C ++错误 - 返回一个char数组

时间:2011-01-17 18:43:34

标签: c++ c

请考虑以下代码:

char CeaserCrypt(char str[256],int key)
{
    char encrypted[256],encryptedChar;
    int currentAsci;

    encrypted[0] = '\0'; 

    for(int i = 0; i < strlen(str); i++) 
    {
        currentAsci = (int)str[i];
        encryptedChar = (char)(currentAsci+key);
        encrypted[i] = encryptedChar;
    }

    return encrypted;
}

Visual Studio 2010出错,因为该函数返回一个数组。我该怎么办?

我的朋友告诉我将签名更改为void CeaserCrypt(char str[256], char encrypted[256], int key)。但我不认为这是正确的。如何摆脱编译错误?

9 个答案:

答案 0 :(得分:7)

返回类型应为char *,但这只会增加另一个问题。

encryptedCeaserCrypt的堆栈上被“分配”,并且在函数返回时可能无效。由于encrypted与输入的长度相同,请执行:

int len = strlen(str);
char *encrypted = (char *) malloc(len+1);

encrypted[len] = '\0';

for (int i = 0; i < len; i++) {
// ...
}

不要忘记稍后释放缓冲区(使用free())。

编辑: @Yosy:不要觉得有必要复制/粘贴。将其用作指针以改善编码习惯。另外,为了满足批评者:使用上面的示例将已分配的指针传递给加密例程。

答案 1 :(得分:6)

它希望您返回char *而不是char。无论如何,您不应该返回引用或指向您在堆栈上创建的内容的指针。在堆栈上分配的东西有a lifetime that corresponds with their scope。范围结束后,允许那些堆栈变量消失。

返回std::vector而不是数组。

std::vector<char> CeaserCrypt(char str[256],int key)
{
    std::vector<char> encrypted(256);
    char encryptedChar;
    int currentAsci;

    encrypted[0] = '\0'; 

    for(int i = 0; i < strlen(str); ++i) 
    {
        currentAsci = (int)str[i];
        encryptedChar = (char)(currentAsci+key);
        encrypted[i] = encryptedChar;
    }

    return encrypted;
}

虽然存在另一个微妙的问题:你正在将一个整数转换为字符值。 int的最大大小远大于char,因此您的强制转换可能会截断该值。

答案 2 :(得分:3)

由于您使用的是C ++,因此您只需使用std::string即可。但除此之外,你朋友建议的可能是最好的。

答案 3 :(得分:3)

这里有一些问题。首先:

char CeaserCrypt(char str[256],int key)

正如其他人所指出的,您的退货类型不正确。您不能在单个字符中返回整个数组。你可以返回char*,但这会返回一个指向数组的指针,该数组将在堆栈上本地分配,因此一旦删除堆栈帧(基本上是在函数之后)就无效了。在英语中,您将访问该内存地址,但谁知道将会有什么...

正如你的朋友建议的那样,更好的签名是:

void CeaserCrypt(char* encrypted, const char str*, const size_t length ,int key)

我添加了一些内容 - size_t长度,因此您可以处理任何长度的字符串。这样,可以根据需要定义str的大小。只需确保char* encrypted的大小相同。

然后你可以这样做:

for(int i = 0; i < length; i++) 
{
    // ...

为此,调用者需要分配具有相同长度的适当大小的缓冲区,其长度必须在length参数中传入。查找malloc以获取C.如果使用C ++,请使用std::string

答案 4 :(得分:2)

如果需要C兼容性,请加密字符串函数参数。 如果没有,请使用C ++ std :: string而不是C样式字符串。

并且在您的代码中,加密字符串不以'\ 0'

结尾

答案 5 :(得分:1)

原始代码的问题在于,您试图从一个原型返回char*的函数返回一个char指针(本地数组已经衰减)。函数不能在C中返回数组,也不能在C ++中返回。

您的朋友可能建议您以这样的方式更改功能,即调用者负责分配所需的缓冲区。

请注意,以下原型完全相等。您不能将数组作为参数传递给普通函数。

int func(char array[256]);
int func(char* array);

OTOH,你应该(如果可以的话)决定你使用的语言。更好的原版(用C ++编写)。

std::vector<unsigned char> CeaserCrypt(const std::string& str, const int key)
{
    std::vector<unsigned char> encrypted(str.begin(), str.end());
    for (std::vector<unsigned char>::iterator iter = vec.begin();
         iter != vec.end(); ++iter) {
        *iter += key;
    }
    return vec;
}

请注意溢出有符号整数会导致未定义的行为

答案 6 :(得分:0)

VS2010正在“大喊大叫”,因为您正在尝试返回在堆栈上分配的值,并且在函数调用返回后不再有效。

您有两种选择:1)在函数内的堆上分配内存,或者2)使用调用者提供给您的内存。 2号是你朋友的建议,也是一种很好的做事方式。

对于1,您需要调用malloc()new,具体取决于您使用的是C还是C ++。在C中,我有以下内容:

char* encrypted = malloc(256 * sizeof(char));

对于C ++,如果您不想使用字符串,请尝试

char* encrypted = new char[256];

编辑 facepalm 对C噪音感到抱歉,我应该更仔细地看一下这个问题,并意识到你正在使用C ++。

答案 7 :(得分:0)

您可以在适当的位置执行Caesar密码,无需将数组传入和传出。

char * CeaserCrypt(char str[256], int key) 
{     
    for(unsigned i = 0; i < strlen(str); i++)      
    {
        str[i] += key;     
    }
    return str; 
} 

作为进一步的简化,请跳过返回值。

void CeaserCrypt(char str[256], int key) 
{     
    for(unsigned i = 0; i < strlen(str); i++)      
    {
        str[i] += key;     
    }
} 

答案 8 :(得分:-1)

你返回的不是char,而是char数组。尝试将返回类型更改为char *(char *和char数组表面上与编译器相同)

char* CeaserCrypt(char str[256],int key)
编辑:如其他帖子所述,加密数组在函数调用后可能无效。你总是可以为加密做一个新的[]声明,记得以后删除[]。