对于这个问题的无用标题,我事先表示歉意,但似乎没有比这更好的了。
这里的想法是将argv
复制到另一个变量中,本质上是复制它。因此,该函数的基本思想是,使用malloc()
来请求复制空间,然后遍历argv
制作每个元素的副本。
这是我正在使用的代码,开发环境现在是Visual Studio 2019(即使严格来讲不是C编译器...):
// Returns a copy of an array of strings (inteded for argv, but should work with any of them):
wchar_t** copyArgv(size_t argc, wchar_t* argv[]) {
// Allocate space for the array of arguments:
wchar_t** argsCopy = malloc(((argc + 1) * sizeof(wchar_t*)));
if (!argsCopy)
return NULL;
// Copy each one of them:
for (size_t i = 0; i < argc; i++) {
argsCopy[i] = _wcsdup(argv[i]);
if (!argsCopy[i]) {
// Should also free any previous copied string I left that part out in the paste.
free(argsCopy);
return NULL;
}
}
argsCopy[argc] = NULL;
return argsCopy;
}
我一直在尝试不同的方法来复制argv,但是每一个方法都让VS相信当我复制参数时(行:argsCopy[i] = _wcsdup(argv[i]);
),或者在下一行中读取无效数据,这意味着要读取保留空间的边界。
所有这些使我相信问题出在(仅)现在malloc()
调用中,以为参数数组保留空间。
但是我还是要撞墙,试图找出问题所在,我的意思是,我想我要提供足够的空间。
我也尝试过其他编译器,但是Clang和GCC的最新稳定版本似乎未显示任何此类警告。因此,我决定问您,经验丰富的程序员,是否可以发现问题,或者是某种编译器错误(我敢打赌)。
无论如何都要感谢您的时间。
PS。作为参考,以下是VS2019发出的确切警告(在64位编译中):
在作业中:
写入'argsCopy'时缓冲区溢出:可写大小为'(((argc + 1))* sizeof(wchar_t *)''字节,但可能会写入'16'字节。
下一行,测试NULL:
从'argsCopy'读取无效数据:可读大小为'(((argc + 1))* sizeof(wchar_t *)''字节,但可以读取'16'个字节。
答案 0 :(得分:0)
这些是来自静态分析器的警告。例如,它试图识别缓冲区溢出情况。
警告
请务必注意,这些是警告而非错误消息。编译器说可能是潜在错误。静态分析通常是一件困难的事情。
误报
没有缓冲区溢出情况,因此它是误报。我认为,此消息在以后的更新中会消失。
稍微更改代码
如果我们按如下方式更改内存分配行:
wchar_t** argsCopy = (wchar_t**)calloc(argc + 1, sizeof(wchar_t*));
然后,Visual Studio 2019将不再发出警告。
分配的字节数保持不变。但是,警告消失了。
测试
在进行更改之前,“ VS错误”列表如下所示:
应用我提议的更改后,警告消失了:
答案 1 :(得分:0)
但是,在尝试使用Visual Studio的在线副本(https://rextester.com/l/c_online_compiler_visual)之后,我可能会误解,我被迫假定您忘记包含string.h
或wchar.h
(两个都可以)。 Visual Studio似乎假定您的返回类型是整数而不是wchar_t *,因为未定义函数。由于它是一个以_
开头的保留函数,因此似乎没有“魔术”,因此它不会发出其他警告吗?再次没有您的确切环境,尽管我被迫部分猜测(您对目标更改警告的评论为我提供了希望正确的提示)。
答案 2 :(得分:0)
关键点可能是您没有分配足够的空间来容纳要复制的数据。
我不知道我是否真正了解您要做什么,我假设您想将二维字符数组复制到另一个内存段中,然后返回其地址,并且该数组具有“ argc”行,即地址每行字符串的行存储在argv数组中。
但是为什么您使用argc+1
而不是argc
?是否有malloc
的额外空间来防止缓冲区溢出?更重要的是sizeof(wchar_t*)
将返回指针的大小(在64位系统中为8个字节)。它不会返回我们想要的二维数组中字符串之一的大小。
答案 3 :(得分:-1)
1)下面说明了一种复制argv的方法,但是。 2)我无法理解为什么要复制argv?它可以解决什么用例/用户问题?
正如我在(1)中提到的,是其中一种方法,本质上是关于将argv的所有内容复制到缓冲区中。这样的事情(PS:当我在出租车上打手机时可能会出现编译错误,因此无法使用高质量的C编译器进行交叉检查)
int numArgc = argc
char** argvCopy;
for (i=0;i<argc,i++)
{
argvCopy[i] = malloc(sizeof(char)*strlen(argv[i]));
strcpy(argvCopy[i], argv[i]);
}
//please do not forget to Free this malloc'ed memory (a very common C programming error) //when you don't need it anymore
请告诉您您要解决的问题