该程序在我的UNIX机器上导致seg故障.我将原因缩小到memset()的第二次调用.
为什么会出现这种情况?代码的第一个"块"几乎与第二个相同,不是吗?为什么第二次调用memset segfault 时没有第一次调用?
我查看了有关segfaulting memset调用的其他线程,但没有一个类似于此.
如果你想知道为什么我写了这么简单的程序,它改编自我写的另一个程序,我用它来教自己如何将memcpy()应用于结构.
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int x;
char text;
} FilesStruct;
int
main(int argc, char** argv)
{
FilesStruct *old_dir;
memset(old_dir,0,sizeof(FilesStruct));
old_dir->x = 3;
old_dir->text = 'c';
printf("old dir: %d,%c\n",old_dir->x,old_dir->text);
FilesStruct *new_dir;
memset(new_dir,0,sizeof(FilesStruct));
new_dir->x = 7;
new_dir->text = 'g';
printf("new dir: %d,%c\n",new_dir->x,new_dir->text);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我使用clang ++来编译程序,我需要在clang ++中编译它而没有错误.我没有得到其他编译器的错误.
代码中的错误行是
memset(grid_, 0, sizeof(int) * x_quadrants * y_quadrants);
Run Code Online (Sandbox Code Playgroud)
整个功能是这样的:
Ocean::Ocean(int num_boats, int x_quadrants, int y_quadrants)
{
grid_ = new int[x_quadrants * y_quadrants];
memset(grid_, 0, sizeof(int) * x_quadrants * y_quadrants);
x_quadrants_ = x_quadrants;
y_quadrants_ = y_quadrants;
boats_ = new Boat[num_boats];
num_boats_ = num_boats;
stats_.hits = 0;
stats_.misses = 0;
stats_.duplicates = 0;
stats_.sunk = 0;
}
Run Code Online (Sandbox Code Playgroud)
我正在使用memset所以当使用不同的驱动程序进行测试时,我不会得到垃圾值输出.没有必要为clang提供命令行,因为我不允许更改它.
这似乎是一个明显的问题,但谷歌没有任何有趣的东西.memset在CUDA内核中使用是否合法:
__device__ void myKernel()
{
int array[10];
memset(array, 0, sizeof(array));
// ...etc...
}
Run Code Online (Sandbox Code Playgroud)
(我知道int array[10] = {0};可能更好,但这只是一个更复杂案例的例子.)
Cppreference 的页面指出std::memset:
std::memsetRun Code Online (Sandbox Code Playgroud)// Defined in header <cstring> void* memset( void* dest, int ch, std::size_t count );[...] 如果对象是潜在重叠的子对象或者不是 TriviallyCopyable(例如,标量、C 兼容结构或普通可复制类型的数组),则行为未定义。
标准中的哪些规则支持这一主张?
我是一个玩memset和指针的新手.
当我编译并运行时:
main(){
int a;
int *b = (int *)malloc(5*sizeof(int));
memset(b,0, 5*sizeof(int));
if (b != NULL){
for(a=0;a<4;a++){
//b[a] = a*a;
printf
("Value of b %u\n", b[a]);
}
}
free(b);
b = NULL;
}
Run Code Online (Sandbox Code Playgroud)
我能够将所有元素值打印为0.但是当我将memset行更改为时
memset(b,0, sizeof(b));
Run Code Online (Sandbox Code Playgroud)
我总是得到一个带有大量数字的元素,我认为它是该元素的地址.但是,尝试在元素上打印地址和值时:
printf("Value of b %u and address %u\n", b[a], b+(a*sizeof(int)));
Run Code Online (Sandbox Code Playgroud)
我得到两个不长的数字.
究竟发生了什么?我是否以错误的方式使用了memset?请告诉我是否需要附上输出截图/澄清我的问题.
谢谢!
从查看CUDA 5.5 API参考和CUDA C编程指南看来,似乎没有cudaCalloc(),与GPU相当的标准C库calloc().
cudaMalloc(),然后cudaMemset()?为什么发布版本memset比visual studio 2012中的调试版本慢?在视觉sutido 2010中,也是这样的结果.我的电脑:
英特尔酷睿i7-3770 3.40GHz 8G内存操作系统:windows 7 sp1 64bit
这是我的测试代码:
#include <boost/progress.hpp>
int main()
{
const int Size = 1000*1024*1024;
char* Data = (char*)malloc(Size);
#ifdef _DEBUG
printf_s("debug\n");
#else
printf_s("release\n");
#endif
boost::progress_timer timer;
memset(Data, 0, Size);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
release
0.27 s
debug
0.06 s
Run Code Online (Sandbox Code Playgroud)
编辑:
if i change code to this, it will get the same result:
#include <boost/progress.hpp>
int main()
{
const int Size = 1000*1024*1024;
char* Data = (char*)malloc(Size);
memset(Data, 1, Size);
#ifdef _DEBUG
printf_s("debug\n");
#else …Run Code Online (Sandbox Code Playgroud) 我已经用值 1 初始化了整个数组,但输出显示了一些垃圾值。但是,如果我使用 0 或 -1 代替 1,该程序可以正常工作。那么,对于可以使用 memset 初始化的值类型是否有一些限制。
int main(){
int a[100];
memset(a,1,sizeof(a));
cout<<a[5]<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用memset以下方法单独设置无符号短变量中的字节:
#include <cstring>
#include <iostream>
int main()
{
unsigned short test2; // 2 bytes
std::cout << "size of test2: " << sizeof(test2) << std::endl;
memset(&test2, 0, 2);
memset(&test2, 0x4D, 1);
memset(&test2+1, 0x42, 1);
std::cout << "value: " << test2 << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出是:
size of test2: 2
value: 77
Run Code Online (Sandbox Code Playgroud)
77是0x4D.所以由于某种原因,它没有拿起我试图在变量的第二个字节上设置的0x42.这是为什么?
我已经研究了一些库的代码,并注意到那里的调用calloc后面跟着memset分配的块calloc.我发现这个问题有一个非常全面的答案,关于calloc和malloc+ 之间的差异,并在分配存储之前memset调用memset:
我仍然无法理解的是为什么人们会这样做.这项业务有什么好处?
上面提到的代码示例库:
light_pcapng_file_info *light_create_default_file_info()
{
light_pcapng_file_info *default_file_info = calloc(1, sizeof(light_pcapng_file_info));
memset(default_file_info, 0, sizeof(light_pcapng_file_info));
default_file_info->major_version = 1;
return default_file_info;
}
Run Code Online (Sandbox Code Playgroud)
分配结构的代码(每个数组包含32个元素):
typedef struct _light_pcapng_file_info {
uint16_t major_version;
uint16_t minor_version;
char *file_comment;
size_t file_comment_size;
char *hardware_desc;
size_t hardware_desc_size;
char *os_desc;
size_t os_desc_size;
char *user_app_desc;
size_t user_app_desc_size;
size_t interface_block_count;
uint16_t link_types[MAX_SUPPORTED_INTERFACE_BLOCKS];
double timestamp_resolution[MAX_SUPPORTED_INTERFACE_BLOCKS];
} light_pcapng_file_info;
Run Code Online (Sandbox Code Playgroud)
编辑:
除了接受的答案,我想提供一些我的同事指出的信息.glibc中有一个错误,有时会阻止calloc将内存清零.这是链接:https: //bugzilla.redhat.com/show_bug.cgi?id = 1293976
案例链接移动时的实际错误报告文本:
glibc:calloc()返回非零内存 …