c++错误-返回一个字符数组

时间:2021-09-03 21:34:27

Consider the following code:

考虑下面的代码:

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 gives an error because the function returns an array. What should I do?

Visual Studio 2010给出一个错误,因为函数返回一个数组。我应该做什么?

My friend told me to change the signature to void CeaserCrypt(char str[256], char encrypted[256], int key). But I don't think that is correct. How can I get rid of the compile error?

我的朋友让我把签名改成void恺撒加密(char str[256], char加密[256],int key)。但我认为这是不对的。如何消除编译错误?

9 个解决方案

#1


7  

The return type should be char * but this'll only add another problem.

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

encrypted is "allocated" on the stack of CeaserCrypt and might not be valid when the function returns. Since encrypted would have the same length as the input, do:

加密的“分配”在堆栈上的不断加密,可能在函数返回时无效。由于加密后的长度与输入相同,请执行以下操作:

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

encrypted[len] = '\0';

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

Don't forget to deallocate the buffer later, though (with free()).

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

EDIT: @Yosy: don't feel obliged to just copy/paste. Use this as a pointer to improve your coding practice. Also, to satisfy criticizers: pass an already allocated pointer to your encryption routine using the above example.

编辑:@Yosy:不要觉得必须复制/粘贴。使用它作为指针来改进您的编码实践。此外,为了满足批评人士的要求:使用上面的示例将已分配的指针传递给加密例程。

#2


6  

It wants you to return a char* rather than a char. Regardless, you shouldn't be returning a reference or a pointer to something you've created on the stack. Things allocated on the stack have a lifetime that corresponds with their scope. After the scope ends, those stack variables are allowed to go away.

它希望您返回一个char*而不是一个char。无论如何,您不应该返回到您在堆栈上创建的某个对象的引用或指针。在堆栈上分配的内容具有与其作用域相对应的生存期。在作用域结束后,允许这些堆栈变量消失。

Return a std::vector instead of an array.

返回一个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;
}

There's another subtle problem there though: you're casting an integer to a character value. The max size of an int is much larger than a char, so your cast may truncate the value.

这里还有一个微妙的问题:您将一个整数赋给一个字符值。int的最大大小比char大得多,所以您的cast可以截断值。

#3


3  

Since you're using C++ you could just use an std::string instead. But otherwise, what your friend suggested is probably best.

因为您使用的是c++,您可以使用std::string代替。但除此之外,你的朋友建议的可能是最好的。

#4


3  

There are a few problems here. First up:

这里有几个问题。首先:

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

As others have pointed out, your return type is incorrect. You cannot return in a single character an entire array. You could return char* but this returns a pointer to an array which will be allocated locally on the stack, and so be invalid once the stack frame is removed (after the function, basically). In English, you'll be accessing that memory address but who knows what's going to be there...

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

As your friend suggested, a better signature would be:

正如你朋友所说,更好的签名应该是:

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

I've added a few things - a size_t length so you can process any length string. This way, the size of str can be defined as needed. Just make sure char* encrypted is of the same size.

我添加了一些东西——size_t长度,所以你可以处理任何长度的字符串。这样,可以根据需要定义str的大小。只要确保加密的char*大小相同。

Then you can do:

然后你可以做:

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

For this to work your caller is going to need to have allocated appropriately-sized buffers of the same length, whose length you must pass in in the length parameter. Look up malloc for C. If C++, use a std::string.

要实现这一点,调用者需要分配大小合适的相同长度的缓冲区,必须在length参数中传递缓冲区的长度。查找malloc查找C。如果是c++,请使用std::string。

#5


2  

If you need C compatibility make encrypted string function argument. If not, than use C++ std::string instead C style string.

如果需要C兼容性,请使用加密字符串函数参数。如果不是,则使用c++ std::string而不是C风格的string。

And also In your code encrypted string isn't ending with '\0'

在你的代码中加密的字符串不是以'\0'结尾的

#6


1  

The problem with the original code is that you are trying to return a char* pointer (to which your local array decayed) from a function that is prototyped as one returning a char. A function cannot return arrays in C, nor in C++.

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

Your friend probably suggested that you change the function in such a way, that the caller is responsible for allocation the required buffer.

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

Do note, that the following prototypes are completely equal. You can't pass an array as a parameter to normal function.

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

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

OTOH, you should (if you can!) decide the language which you use. Better version of the original (in C++).

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;
}

Do note that overflowing a signed integer causes undefined behavior.

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

#7


0  

VS2010 is "yelling" at you because you are trying to return a value that is allocated on the stack, and is no longer valid once your function call returns.

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

You have two choices: 1) Allocate memory on the heap inside your function, or 2) use memory provided to you by the caller. Number 2 is what your friend in suggesting and is a very good way to do things.

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

For 1, you need to call malloc() or new depending on whether you are working in C or C++. In C, I'd have the following:

对于1,您需要调用malloc()或new,这取决于您是在使用C还是c++。在C语言中,我会有以下内容:

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

For C++, if you don't want to use a string, try

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

char* encrypted = new char[256];

Edit: facepalm Sorry about the C noise, I should have looked at the question more closely and realized you are working in C++.

编辑:facepalm很抱歉C噪音太大,我应该更仔细地看一下这个问题,然后才意识到你在使用c++。

#8


0  

You can just do your Ceaser cipher in place, no need to pass arrays in and out.

您可以在适当的位置使用您的“停止密码”,不需要传入和输出数组。

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

As a further simplification, skip the return value.

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

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

#9


-1  

well what you're returning isn't a char, but a char array. Try changing the return type to char*(char* and a char array are ostensibly the same thing for the compiler)

你返回的不是一个char,而是一个char数组。尝试将返回类型更改为char*(char*和char数组表面上对编译器来说是一样的)

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

EDIT: as said in other posts, the encrypted array will probably not be valid after the function call. you could always do a new[] declaration for encrypted, remembering to delete[] it later on.

编辑:如其他文章所述,加密数组在函数调用后可能无效。您可以始终执行一个新的[]声明,以便对其进行加密,并记住稍后删除[]。

#1


7  

The return type should be char * but this'll only add another problem.

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

encrypted is "allocated" on the stack of CeaserCrypt and might not be valid when the function returns. Since encrypted would have the same length as the input, do:

加密的“分配”在堆栈上的不断加密,可能在函数返回时无效。由于加密后的长度与输入相同,请执行以下操作:

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

encrypted[len] = '\0';

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

Don't forget to deallocate the buffer later, though (with free()).

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

EDIT: @Yosy: don't feel obliged to just copy/paste. Use this as a pointer to improve your coding practice. Also, to satisfy criticizers: pass an already allocated pointer to your encryption routine using the above example.

编辑:@Yosy:不要觉得必须复制/粘贴。使用它作为指针来改进您的编码实践。此外,为了满足批评人士的要求:使用上面的示例将已分配的指针传递给加密例程。

#2


6  

It wants you to return a char* rather than a char. Regardless, you shouldn't be returning a reference or a pointer to something you've created on the stack. Things allocated on the stack have a lifetime that corresponds with their scope. After the scope ends, those stack variables are allowed to go away.

它希望您返回一个char*而不是一个char。无论如何,您不应该返回到您在堆栈上创建的某个对象的引用或指针。在堆栈上分配的内容具有与其作用域相对应的生存期。在作用域结束后,允许这些堆栈变量消失。

Return a std::vector instead of an array.

返回一个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;
}

There's another subtle problem there though: you're casting an integer to a character value. The max size of an int is much larger than a char, so your cast may truncate the value.

这里还有一个微妙的问题:您将一个整数赋给一个字符值。int的最大大小比char大得多,所以您的cast可以截断值。

#3


3  

Since you're using C++ you could just use an std::string instead. But otherwise, what your friend suggested is probably best.

因为您使用的是c++,您可以使用std::string代替。但除此之外,你的朋友建议的可能是最好的。

#4


3  

There are a few problems here. First up:

这里有几个问题。首先:

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

As others have pointed out, your return type is incorrect. You cannot return in a single character an entire array. You could return char* but this returns a pointer to an array which will be allocated locally on the stack, and so be invalid once the stack frame is removed (after the function, basically). In English, you'll be accessing that memory address but who knows what's going to be there...

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

As your friend suggested, a better signature would be:

正如你朋友所说,更好的签名应该是:

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

I've added a few things - a size_t length so you can process any length string. This way, the size of str can be defined as needed. Just make sure char* encrypted is of the same size.

我添加了一些东西——size_t长度,所以你可以处理任何长度的字符串。这样,可以根据需要定义str的大小。只要确保加密的char*大小相同。

Then you can do:

然后你可以做:

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

For this to work your caller is going to need to have allocated appropriately-sized buffers of the same length, whose length you must pass in in the length parameter. Look up malloc for C. If C++, use a std::string.

要实现这一点,调用者需要分配大小合适的相同长度的缓冲区,必须在length参数中传递缓冲区的长度。查找malloc查找C。如果是c++,请使用std::string。

#5


2  

If you need C compatibility make encrypted string function argument. If not, than use C++ std::string instead C style string.

如果需要C兼容性,请使用加密字符串函数参数。如果不是,则使用c++ std::string而不是C风格的string。

And also In your code encrypted string isn't ending with '\0'

在你的代码中加密的字符串不是以'\0'结尾的

#6


1  

The problem with the original code is that you are trying to return a char* pointer (to which your local array decayed) from a function that is prototyped as one returning a char. A function cannot return arrays in C, nor in C++.

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

Your friend probably suggested that you change the function in such a way, that the caller is responsible for allocation the required buffer.

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

Do note, that the following prototypes are completely equal. You can't pass an array as a parameter to normal function.

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

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

OTOH, you should (if you can!) decide the language which you use. Better version of the original (in C++).

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;
}

Do note that overflowing a signed integer causes undefined behavior.

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

#7


0  

VS2010 is "yelling" at you because you are trying to return a value that is allocated on the stack, and is no longer valid once your function call returns.

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

You have two choices: 1) Allocate memory on the heap inside your function, or 2) use memory provided to you by the caller. Number 2 is what your friend in suggesting and is a very good way to do things.

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

For 1, you need to call malloc() or new depending on whether you are working in C or C++. In C, I'd have the following:

对于1,您需要调用malloc()或new,这取决于您是在使用C还是c++。在C语言中,我会有以下内容:

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

For C++, if you don't want to use a string, try

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

char* encrypted = new char[256];

Edit: facepalm Sorry about the C noise, I should have looked at the question more closely and realized you are working in C++.

编辑:facepalm很抱歉C噪音太大,我应该更仔细地看一下这个问题,然后才意识到你在使用c++。

#8


0  

You can just do your Ceaser cipher in place, no need to pass arrays in and out.

您可以在适当的位置使用您的“停止密码”,不需要传入和输出数组。

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

As a further simplification, skip the return value.

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

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

#9


-1  

well what you're returning isn't a char, but a char array. Try changing the return type to char*(char* and a char array are ostensibly the same thing for the compiler)

你返回的不是一个char,而是一个char数组。尝试将返回类型更改为char*(char*和char数组表面上对编译器来说是一样的)

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

EDIT: as said in other posts, the encrypted array will probably not be valid after the function call. you could always do a new[] declaration for encrypted, remembering to delete[] it later on.

编辑:如其他文章所述,加密数组在函数调用后可能无效。您可以始终执行一个新的[]声明,以便对其进行加密,并记住稍后删除[]。