I have encountered with interesting situation when initializing dynamic size variables.
在初始化动态大小变量时,我遇到了一个有趣的情况。
For example:
例如:
// getInput() is some magic method to retrieve input with dynamic length string
// some times it can be 10, some times 99 and so on
char vector[strlen(getInput())] = getInput();
In this case definitely wont work since compiler can't allocate some fixed size memory to heap, that's right?
在这种情况下,编译器肯定不能工作,因为编译器不能为堆分配一些固定大小的内存,对吗?
But in this case, it works fine:
但在这种情况下,它很有效:
char path[] = "";
strcpy(path, getInput());
Why it doesn't work in first case and works in second? Is maybe strcpy
uses malloc
or something?
为什么它在第一种情况下无效,在第二种情况下有效?是不是strcpy用了malloc之类的?
3 个解决方案
#1
12
char vector[strlen(getInput())] = getInput();
演示了getInput())char向量[strlen()演示了getInput()=;
Calling the getInput() function twice in the same expression doesn't make any sense. In particular, you don't copy strings with the =
operator but with strcpy()
. Also, you need to allocate space for the null terminator.
在同一个表达式中调用getInput()函数两次没有任何意义。特别是,您不使用=操作符复制字符串,而是使用strcpy()。此外,还需要为空终止符分配空间。
Assuming these are local variables (they should be), what you should do instead is this:
假设这些是局部变量(应该是),那么您应该做的是:
int main (void)
{
const char* input = getInput();
char vector[strlen(input) + 1];
strcpy(vector, input);
...
}
But in this case, it works fine:
但在这种情况下,它很有效:
char path[] = "";
strcpy(path, getInput());
char[]= " ";路径演示了getInput()strcpy(路径,);
No, it doesn't work fine! All you did was do declare a static array of size 1 (size of the null terminator), then you copy data of longer length into that array. This causes an array out of bounds bug which is undefined behavior, anything can happen. Unfortunately, it caused your program to seem to work ok, while it actually has a latent severe bug.
不,它不能正常工作!您所做的只是声明一个大小为1的静态数组(null终止符的大小),然后将较长的数据复制到该数组中。这会导致数组越界错误,这是未定义的行为,任何事情都可能发生。不幸的是,它使您的程序看起来运行良好,而实际上它有一个潜在的严重bug。
#2
1
char vector[strlen(getInput())] = getInput();
You are mixing a char array initialization expected by char vector[strlen(getInput())] =
with the assignment of a array pointer returned by getInput()
.
您将char数组初始化与getInput()返回的数组指针的赋值混合在一起。
Possible Solutions
可能的解决方案
You can either initialize the array with values
可以使用值初始化数组
char vector[strlen(getInput())] = { 'a', 'b', .. 'z' };
Or obtain the array pointer returned by getInput
或获取getInput返回的数组指针
const char * vector = getInput();
Or copy the array returned by getInput
into vector array
或者将getInput返回的数组复制到向量数组中
const char * input = getInput();
const size_t size = strlen(input);
char vector [size+1] = { 0 };
memset(vector , '\0', sizeof(vector));
strcpy(vector,input);
#3
-1
It seems like the function getInput returns a character pointer, so you cannot assign the result to an array. Also in
函数getInput似乎返回一个字符指针,因此不能将结果分配给数组。也在
char path[] = "";
the length of path is only one character (the null character), so copying the input to this variable is only valid if the input is the empty string.
路径的长度仅为一个字符(null字符),因此只有在输入为空字符串时,将输入复制到该变量才是有效的。
You probably want something like this:
你可能想要这样的东西:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NEW_ARRAY(ptr, n) \
{ \
(ptr) = malloc((n) * sizeof (ptr)[0]); \
if ((ptr) == NULL) { \
fprintf(stderr, "error: Memory exhausted\n"); \
exit(EXIT_FAILURE); \
} \
}
const char *getInput(void);
int main(void)
{
const char *input;
char *inputCopy;
int inputLength;
input = getInput();
inputLength = strlen(input);
NEW_ARRAY(inputCopy, inputLength + 1);
strcpy(inputCopy, input);
return 0;
}
#1
12
char vector[strlen(getInput())] = getInput();
演示了getInput())char向量[strlen()演示了getInput()=;
Calling the getInput() function twice in the same expression doesn't make any sense. In particular, you don't copy strings with the =
operator but with strcpy()
. Also, you need to allocate space for the null terminator.
在同一个表达式中调用getInput()函数两次没有任何意义。特别是,您不使用=操作符复制字符串,而是使用strcpy()。此外,还需要为空终止符分配空间。
Assuming these are local variables (they should be), what you should do instead is this:
假设这些是局部变量(应该是),那么您应该做的是:
int main (void)
{
const char* input = getInput();
char vector[strlen(input) + 1];
strcpy(vector, input);
...
}
But in this case, it works fine:
但在这种情况下,它很有效:
char path[] = "";
strcpy(path, getInput());
char[]= " ";路径演示了getInput()strcpy(路径,);
No, it doesn't work fine! All you did was do declare a static array of size 1 (size of the null terminator), then you copy data of longer length into that array. This causes an array out of bounds bug which is undefined behavior, anything can happen. Unfortunately, it caused your program to seem to work ok, while it actually has a latent severe bug.
不,它不能正常工作!您所做的只是声明一个大小为1的静态数组(null终止符的大小),然后将较长的数据复制到该数组中。这会导致数组越界错误,这是未定义的行为,任何事情都可能发生。不幸的是,它使您的程序看起来运行良好,而实际上它有一个潜在的严重bug。
#2
1
char vector[strlen(getInput())] = getInput();
You are mixing a char array initialization expected by char vector[strlen(getInput())] =
with the assignment of a array pointer returned by getInput()
.
您将char数组初始化与getInput()返回的数组指针的赋值混合在一起。
Possible Solutions
可能的解决方案
You can either initialize the array with values
可以使用值初始化数组
char vector[strlen(getInput())] = { 'a', 'b', .. 'z' };
Or obtain the array pointer returned by getInput
或获取getInput返回的数组指针
const char * vector = getInput();
Or copy the array returned by getInput
into vector array
或者将getInput返回的数组复制到向量数组中
const char * input = getInput();
const size_t size = strlen(input);
char vector [size+1] = { 0 };
memset(vector , '\0', sizeof(vector));
strcpy(vector,input);
#3
-1
It seems like the function getInput returns a character pointer, so you cannot assign the result to an array. Also in
函数getInput似乎返回一个字符指针,因此不能将结果分配给数组。也在
char path[] = "";
the length of path is only one character (the null character), so copying the input to this variable is only valid if the input is the empty string.
路径的长度仅为一个字符(null字符),因此只有在输入为空字符串时,将输入复制到该变量才是有效的。
You probably want something like this:
你可能想要这样的东西:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NEW_ARRAY(ptr, n) \
{ \
(ptr) = malloc((n) * sizeof (ptr)[0]); \
if ((ptr) == NULL) { \
fprintf(stderr, "error: Memory exhausted\n"); \
exit(EXIT_FAILURE); \
} \
}
const char *getInput(void);
int main(void)
{
const char *input;
char *inputCopy;
int inputLength;
input = getInput();
inputLength = strlen(input);
NEW_ARRAY(inputCopy, inputLength + 1);
strcpy(inputCopy, input);
return 0;
}