内存泄漏是指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。
我们平时开发过程中不可避免的会遇到内存泄漏问题,你是如何排查的呢?估计你是使用下面这几个工具吧?
这里程序喵向大家推荐新的一个排查内存泄漏的工具:AddressSanitizer(ASan),该工具为gcc自带,4.8以上版本都可以使用,支持Linux、OS、Android等多种平台,不止可以检测内存泄漏,它其实是一个内存错误检测工具,可以检测的问题有:
使用方法直接看我下面的代码:
检测内存泄漏
内存泄漏代码:
#include <stdlib.h>
void func1() { malloc(7); }
void func2() { malloc(5); }
int main() {
func1();
func2();
return 0;
}
编译and输出:
g++ -fsanitize=address -g test_leak.cc && ./a.out
=================================================================
==103==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 7 byte(s) in 1 object(s) allocated from:
#0 0x7f95b231eb40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40)
#1 0x7f95b36007f7 in func1() /home/wangzhiqiang/test/test_leak.cc:3
#2 0x7f95b3600814 in main /home/wangzhiqiang/test/test_leak.cc:8
#3 0x7f95b1e61b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
Direct leak of 5 byte(s) in 1 object(s) allocated from:
#0 0x7f95b231eb40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40)
#1 0x7f95b3600808 in func2() /home/wangzhiqiang/test/test_leak.cc:5
#2 0x7f95b3600819 in main /home/wangzhiqiang/test/test_leak.cc:9
#3 0x7f95b1e61b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
SUMMARY: AddressSanitizer: 12 byte(s) leaked in 2 allocation(s).
编译方式很简单,只需要添加-fsanitize=address -g就可以检测出具体产生内存泄漏的位置以及泄漏空间的大小。
检测堆栈内存越界访问
示例:
#include <iostream>
int main() {
int *array = new int[100];
array[0] = 0;
int res = array[100]; // out of bounds
delete[] array;
return res;
}
编译and输出:
g++ -fsanitize=address -g test_leak.cc && ./a.out
=================================================================
==110==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6140000001d0 at pc 0x7f0e06400d2e bp 0x7ffff5963f10 sp 0x7ffff5963f00
READ of size 4 at 0x6140000001d0 thread T0
#0 0x7f0e06400d2d in main /home/wangzhiqiang/test/test_leak.cc:6
#1 0x7f0e048d1b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#2 0x7f0e06400bb9 in _start (/mnt/d/wzq/wzq/util/test/a.out+0xbb9)
0x6140000001d0 is located 0 bytes to the right of 400-byte region [0x614000000040,0x6140000001d0)
allocated by thread T0 here:
#0 0x7f0e05120608 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0608)
#1 0x7f0e06400cab in main /home/wangzhiqiang/test/test_leak.cc:4
#2 0x7f0e048d1b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/wangzhiqiang/test/test_leak.cc:6 in main
Shadow bytes around the buggy address:
0x0c287fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c287fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c287fff8000: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
0x0c287fff8010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c287fff8020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c287fff8030: 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa
0x0c287fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==110==ABORTING
可以方便定位到堆栈内存越界访问的错误。
全局内存越界访问:
示例:
#include <iostream>
int global_array[100] = {0};
int main() {
int res = global_array[100]; // out of bounds
return 0;
}
编译and输出:
g++ -fsanitize=address -g test_leak.cc && ./a.out
=================================================================
==116==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7f42e6e02310 at pc 0x7f42e6c00c84 bp 0x7fffdda52780 sp 0x7fffdda52770
READ of size 4 at 0x7f42e6e02310 thread T0
#0 0x7f42e6c00c83 in main /home/wangzhiqiang/test/test_leak.cc:6
#1 0x7f42e50d1b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#2 0x7f42e6c00b69 in _start (/mnt/d/wzq/wzq/util/test/a.out+0xb69)
0x7f42e6e02310 is located 0 bytes to the right of global variable 'global_array' defined in 'test_leak.cc:3:5' (0x7f42e6e02180) of size 400
SUMMARY: AddressSanitizer: global-buffer-overflow /home/wangzhiqiang/test/test_leak.cc:6 in main
Shadow bytes around the buggy address:
0x0fe8dcdb8410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe8dcdb8420: 00 00 00 00 00 00 00 00 01 f9 f9 f9 f9 f9 f9 f9
0x0fe8dcdb8430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe8dcdb8440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe8dcdb8450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0fe8dcdb8460: 00 00[f9]f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00
0x0fe8dcdb8470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe8dcdb8480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe8dcdb8490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe8dcdb84a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe8dcdb84b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==116==ABORTING
局部内存被外层使用
示例:
#include <iostream>
volatile int *p = 0;
int main() {
{
int x = 0;
p = &x;
}
*p = 5;
return 0;
}
编译and输出:
g++ -fsanitize=address -g test_leak.cc && ./a.out
=================================================================
==243==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7fffce12a4b0 at pc 0x7f3993e00e7e bp 0x7fffce12a480 sp 0x7fffce12a470
WRITE of size 4 at 0x7fffce12a4b0 thread T0
#0 0x7f3993e00e7d in main /home/wangzhiqiang/test/test_leak.cc:10
#1 0x7f39922d1b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#2 0x7f3993e00c89 in _start (/mnt/d/wzq/wzq/util/test/a.out+0xc89)
Address 0x7fffce12a4b0 is located in stack of thread T0 at offset 32 in frame
#0 0x7f3993e00d79 in main /home/wangzhiqiang/test/test_leak.cc:5
This frame has 1 object(s):
[32, 36) 'x' <== Memory access at offset 32 is inside this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-use-after-scope /home/wangzhiqiang/test/test_leak.cc:10 in main
Shadow bytes around the buggy address:
0x100079c1d440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100079c1d450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100079c1d460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100079c1d470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100079c1d480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100079c1d490: 00 00 f1 f1 f1 f1[f8]f2 f2 f2 00 00 00 00 00 00
0x100079c1d4a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100079c1d4b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100079c1d4c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100079c1d4d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100079c1d4e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==243==ABORTING
free后被使用
示例:
#include <iostream>
int main() {
int *array = new int[100];
delete[] array;
int a = array[0]; // error
return 0;
}
编译and输出:
g++ -fsanitize=address -g test_leak.cc && ./a.out
=================================================================
==282==ERROR: AddressSanitizer: heap-use-after-free on address 0x614000000040 at pc 0x7f209fa00caa bp 0x7ffff2a15020 sp 0x7ffff2a15010
READ of size 4 at 0x614000000040 thread T0
#0 0x7f209fa00ca9 in main /home/wangzhiqiang/test/test_leak.cc:6
#1 0x7f209ded1b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#2 0x7f209fa00b69 in _start (/mnt/d/wzq/wzq/util/test/a.out+0xb69)
0x614000000040 is located 0 bytes inside of 400-byte region [0x614000000040,0x6140000001d0)
freed by thread T0 here:
#0 0x7f209e721480 in operator delete[](void*) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe1480)
#1 0x7f209fa00c72 in main /home/wangzhiqiang/test/test_leak.cc:5
#2 0x7f209ded1b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
previously allocated by thread T0 here:
#0 0x7f209e720608 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0608)
#1 0x7f209fa00c5b in main /home/wangzhiqiang/test/test_leak.cc:4
#2 0x7f209ded1b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
SUMMARY: AddressSanitizer: heap-use-after-free /home/wangzhiqiang/test/test_leak.cc:6 in main
Shadow bytes around the buggy address:
0x0c287fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c287fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c287fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c287fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c287fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c287fff8000: fa fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd
0x0c287fff8010: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c287fff8020: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c287fff8030: fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa
0x0c287fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c287fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==282==ABORTING
Initialization order bugs
示例,这里有两个文件:
// test_memory1.cc
#include <stdio.h>
extern int extern_global;
int read_extern_global() { return extern_global; }
int x = read_extern_global() + 1;
int main() {
printf("%d\n", x);
return 0;
}
// test_memory2.cc
int foo() { return 123; }
int extern_global = foo();
第一种编译方式输出如下:
g++ test_memory1.cc test_memory2.cc && ./a.out
1
第二种编译方式输出如下:
g++ test_memory2.cc test_memory1.cc && ./a.out
124
这种问题我们平时编程过程中可以都不会太注意,然而通过ASan可以检测出这种潜在的bug:
编译and输出:
g++ -fsanitize=address -g test_memory1.cc test_memory2.cc
ASAN_OPTIONS=check_initialization_order=true:strict_init_order=true ./a.out
=================================================================
==419==ERROR: AddressSanitizer: initialization-order-fiasco on address 0x7f46c20021a0 at pc 0x7f46c1e00c28 bp 0x7fffe423d920 sp 0x7fffe423d910
READ of size 4 at 0x7f46c20021a0 thread T0
#0 0x7f46c1e00c27 in read_extern_global() /home/wangzhiqiang/test/test_memory1.cc:3
#1 0x7f46c1e00cb3 in __static_initialization_and_destruction_0 /home/wangzhiqiang/test/test_memory1.cc:4
#2 0x7f46c1e00d0a in _GLOBAL__sub_I__Z18read_extern_globalv /home/wangzhiqiang/test/test_memory1.cc:8
#3 0x7f46c1e00e5c in __libc_csu_init (/mnt/d/wzq/wzq/util/test/a.out+0xe5c)
#4 0x7f46c0461b27 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b27)
#5 0x7f46c1e00b09 in _start (/mnt/d/wzq/wzq/util/test/a.out+0xb09)
0x7f46c20021a0 is located 0 bytes inside of global variable 'extern_global' defined in 'test_memory2.cc:2:5' (0x7f46c20021a0) of size 4
registered at:
#0 0x7f46c08764a8 (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x364a8)
#1 0x7f46c1e00e0b in _GLOBAL__sub_I_00099_1__Z3foov (/mnt/d/wzq/wzq/util/test/a.out+0xe0b)
#2 0x7f46c1e00e5c in __libc_csu_init (/mnt/d/wzq/wzq/util/test/a.out+0xe5c)
SUMMARY: AddressSanitizer: initialization-order-fiasco /home/wangzhiqiang/test/test_memory1.cc:3 in read_extern_global()
Shadow bytes around the buggy address:
0x0fe9583f83e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe9583f83f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe9583f8400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe9583f8410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe9583f8420: 00 00 00 00 00 00 00 00 04 f9 f9 f9 f9 f9 f9 f9
=>0x0fe9583f8430: 00 00 00 00[f6]f6 f6 f6 f6 f6 f6 f6 00 00 00 00
0x0fe9583f8440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe9583f8450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe9583f8460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe9583f8470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0fe9583f8480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==419==ABORTING
注意:这里在运行程序前需要添加环境变量:
ASAN_OPTIONS=check_initialization_order=true:strict_init_order=true
小总结
ASan是个很好的检测内存问题的工具,不需要配置环境,使用还方便,编译时只需要-fsanitize=address -g就可以,运行程序时候可以选择添加对应的ASAN_OPTIONS环境变量就可以检测出很多内存问题。它的错误信息也很有用,明确指出当前是什么类型的内存错误,如:
具体可以看google的官方文档:https://github.com/google/sanitizers/wiki/AddressSanitizer
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。