我想在我的iOS应用程序中清除内存中的敏感数据.在Windows中我曾经使用过SecureZeroMemory.现在,在iOS中,我使用普通的旧memset,但我有点担心编译器可能会优化它:https: //buildsecurityin.us-cert.gov/bsi/articles/knowledge/coding/771-BSI.html
代码段:
NSData *someSensitiveData;
memset((void *)someSensitiveData.bytes, 0, someSensitiveData.length);
Run Code Online (Sandbox Code Playgroud) #include "stdlib.h"
#include "stdio.h"
#include "string.h"
int main(int argc, char* argv[])
{
int *test = malloc(15 * sizeof(int));
for(int i = 0;i < 15 ;i ++ )
printf("test is %i\n",test[i]);
memset(test,0,sizeof(int) * 15);
for(int i = 0 ; i < 15; i ++ )
printf("test after memset is %i\n",test[i]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出非常奇怪:
test is 1142126264
test is 32526
...
test is 1701409394
test is 1869348978
test is 1694498930
test after memset is 0
test after memset is 0
test …
Run Code Online (Sandbox Code Playgroud) 这是我想要编写的代码:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
int main(int argc, char *argv[])
{
float arry[3] = {0};
memset(arry, (int) 10.0, 3*sizeof(float));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是我想看看是否可以使用memset使数组的每个条目都是0以外的数字.但是,在单步执行该行之后,数组内容会变为非常小的数字(0).我想知道在这种情况下我使用memset()函数做错了什么.我希望这不是一个重复的帖子,因为我输入的内容似乎没有任何建议的相关问题.
一般来说,根据C标准,保证带有0的memset()会将C结构中的填充位清零吗?
那gcc怎么样?
例如,类似于:
struct MyStruct
{
unsigned char member1;
unsigned int member2;
char member3;
unsigned char member4;
float member5;
};
struct MyStruct ms;
memset(&ms, 0, sizeof( struct MyStruct));
Run Code Online (Sandbox Code Playgroud) 是否有一个等同于RtlSecureZeroMemory
/ 的Mac OS X SecureZeroMemory
,一个将一块内存归零的函数,但编译器不会优化调用?
是否有任何明确的指南说我们必须将sockaddr_in结构初始化为零,原因是什么?
// IPv4 AF_INET sockets:
struct sockaddr_in {
short sin_family; // e.g. AF_INET, AF_INET6
unsigned short sin_port; // e.g. htons(3490)
struct in_addr sin_addr; // see struct in_addr, below
char sin_zero[8]; // zero this if you want to
};
Run Code Online (Sandbox Code Playgroud)
每当我查看真实的代码或示例或书籍时,它总是具有类似于以下的代码结构:
struct sockaddr_in foo;
memset(&foo, 0, sizeof(foo));
foo.sin_port = htons(1025);
foo.sin_family = AF_INET;
inet_pton(AF_INET, "10.0.0.1", &foo.sin_addr);
Run Code Online (Sandbox Code Playgroud)
我知道有些消息来源说char sin_zero[8]
会员在那里填充,应该设置为零,但为什么要将其余部分归零.特别是在大多数情况下,在接下来的几行声明中对它们进行初始化.即使是sin_zero成员,beej编程指南也表示不再强制将它们归零.我已经搜索了一个解释,但没有提到任何重点.这个堆栈溢出问题对初始化本身有一些不同的建议,但没有解释为什么归零是必要的.
这是遗留的做法还是有一些我错过的真正原因?任何参考表示赞赏.
我应该如何将匿名联盟归零?我在cppreference页面上找不到任何关于它的内容.将memset
荷兰国际集团是最大的成员与0
在这里工作?
例如 -
#include <iostream>
#include <cstring>
struct s{
char a;
char b[100];
};
int main(){
union {
int a;
s b;
char c;
};
// b.a = 'a'; (1)
std::memset(&b, 0, sizeof(b));
std::cout << a << "\n";
std::cout << b.a << " " << b.b << "\n";
std::cout << c << "\n";
}
Run Code Online (Sandbox Code Playgroud)
如果这样可行,我应该在使用memset()
激活最大的成员之前取消注释(1)吗?
我很好奇在类似下面的情况下使用memset()在效率方面是否有任何优势.
鉴于以下缓冲区声明......
struct More_Buffer_Info
{
unsigned char a[10];
unsigned char b[10];
unsigned char c[10];
};
struct My_Buffer_Type
{
struct More_Buffer_Info buffer_info[100];
};
struct My_Buffer_Type my_buffer[5];
unsigned char *p;
p = (unsigned char *)my_buffer;
Run Code Online (Sandbox Code Playgroud)
除了少量代码之外,使用它还有一个优势:
memset((void *)p, 0, sizeof(my_buffer));
Run Code Online (Sandbox Code Playgroud)
在此:
for (i = 0; i < sizeof(my_buffer); i++)
{
*p++ = 0;
}
Run Code Online (Sandbox Code Playgroud) 在严格别名方面,这段代码是明确定义的行为吗?
_Bool* array = malloc(n);
memset(array, 0xFF, n);
_Bool x = array[0];
Run Code Online (Sandbox Code Playgroud)
有效类型的规则具有memcpy
和memmove
(C176.5§6)的特殊情况,但不适用于memset
.
我认为有效的类型就变成了unsigned char
.因为第二个参数memset
需要转换为unsigned char
(C17 7.24.6.1)并且由于有效类型的规则,(C176.5§6):
...或者被复制为字符类型数组,然后该访问的修改对象的有效类型以及不修改该值的后续访问是从中复制值的对象的有效类型,如果它有一个.
array
后存储的数据的有效类型是memset
什么?array[0]
访问是否违反了严格的别名?因为_Bool
不是严格别名规则中排除的类型(与字符类型不同).来自在线文档:
cudaError_t cudaMemset (void * devPtr, int value, size_t count )
Run Code Online (Sandbox Code Playgroud)
使用常量字节值填充devPtr指向的内存区域的第一个计数字节.
参数:devPtr -指向设备存储器值-值设置每个字节指定的存储器计数-大小在字节设置
此描述似乎不正确:
int *dJunk;
cudaMalloc((void**)&dJunk, 32*(sizeof(int));
cudaMemset(dJunk, 0x12, 32);
Run Code Online (Sandbox Code Playgroud)
将所有32个整数设置为0x12,而不是0x12121212.(Int vs Byte)
描述讨论了设置字节.计数和值以字节为单位进行描述.通知计数的类型为size_t,值的类型为int.即将字节大小设置为int值.
编程指南中未提及cudaMemset().我必须假设我看到的行为是正确的,文档很糟糕.
那里有更好的文档来源吗?(在哪里?)
是否支持其他类型?即会float *dJunk;
工作吗?其他?