首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >警告:带有GCC 11.2.1的空目标指针[-Wformat-溢出=]

警告:带有GCC 11.2.1的空目标指针[-Wformat-溢出=]
EN

Stack Overflow用户
提问于 2022-07-16 20:02:12
回答 2查看 176关注 0票数 2

这是我的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <cstdio>

int main()
{
    char *str = new char[64] ;
    std::sprintf(str, "msg: %s", "hello world") ;

    std::cout << str << std::endl ;
    delete [] str ;

    return 0 ;
}

使用GCC 11.2.1,使用以下命令:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
g++ -O -fsanitize=undefined -Wformat-overflow test.cpp

我得到:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
test.cpp:7:17: warning: null destination pointer [-Wformat-overflow=]
    7 |     std::sprintf(str, "msg: %s", "hello world") ;
      |     ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我不明白发出警告的原因。我做错什么了吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-07-16 20:48:51

这似乎是来自g++编译器的错误/假阳性警告。该消息试图警告您,如果指针为null (或指向大小不足的缓冲区),则使用指针变量作为sprintf函数的目标可能会失败。

抑制此警告是“微不足道的”:只需在调用str之前添加一个str不为空的检查即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (str) std::sprintf(str, "msg: %s", "hello world");

但是,您的代码是好的,而且这种检查是完全多余的,因为标准运算符new [] (正如您使用的那样),不能返回空指针。您使用的是new的“版本(2)”,如此cppreference首选项页面所述。注:同一页:

将值1-4)非空指针返回到大小至少为size的适当对齐内存。

如果您的new char[64]表达式未能分配足够的内存,那么将抛出一个异常,并且(如您的代码所示)将不会调用sprintf函数。

票数 3
EN

Stack Overflow用户

发布于 2022-07-16 21:33:59

为了补充禤浩焯的答案,尽管你的代码是正确的,GCC发出警告的原因是对delete[]的明确调用。我发现注释掉这一行删除了警告。我认为GCC是在一个简单的上下文中看到delete[]调用的(可能是因为它在析构函数之外),它认为内存在使用时可能被释放。

如果使用gcc命令将代码移动到纯C上下文(使用malloc和free),则警告仍然存在,这意味着它可能检测空闲(使用free()delete[]),并警告您数据可能是在空闲后读写(即使在本例中不是)。GCC没有删除char数组指针的副本可能是一个错误,但我不太确定。上面可能有GCC的窃听器报告,但我找不到。这是我测试的代码。

注: GCC版本: 11.3.0,虽略有增加,但仍坚持GCC-11.我仍然使用与您的示例相同的标志/选项。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdlib.h>
#include <stdio.h>

int main()
{
    char* str = (char*)malloc(sizeof(char) * 64);

    sprintf(str, "msg: %s", "hello world");
    
    printf("%s\n", str);

    free(str);

    return 0;
}

但是,在具体使用g++时,如果您使用malloc并释放它,它将出于某种原因删除警告。以下是相应的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <cstdio>

int main()
{
    char* str = (char*)std::malloc(sizeof(char) * 64);

    std::sprintf(str, "msg: %s", "hello world");
    
    std::cout << str << std::endl;

    std::free(str);

    return 0;
}

注意:我使用std::cout来保持与给定代码的一致性,并且如果我使用std::printf,则警告仍然存在。

如果您专门使用C++,则可以使用std::string

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <string>
#include <cstdio>

int main()
{
    std::string str(64, ' ');  ///< allocate a std::string with 64 characters, each initialised to a space (' ').

    std::sprintf(&str[0], "msg: %s", "hello world");  ///< Get the pointer to the first value (C-style) by indexing the string and using the address operator (&)
    
    std::cout << str << std::endl;

    return 0;
}

上面的代码没有手动内存管理,它是由std::string完成的。不过,如果您正在学习C++中的内存功能,我确实理解它。希望这一切都很清楚。

注意:std::string的c_str()方法在这里不适用于std::sprintf,因为它需要一个char*,但是c_str()返回一个const char*

注意:是的,我知道&也可以是引用运算符或位和运算符,但是在这种情况下,它被用来获得C中的地址。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73009176

复制
相关文章
内存溢出、内存泄露、野指针、空指针
看到下面代码的情况,如果使用while循环一直调用GetMemory,一直malloc内存,但是没有使用free函数释放内存,会导致最后没有空间分配,产生的这种情况就是内存溢出
opencode
2022/12/26
8880
空指针的传说
他原本不叫这个名字,空指针原本复姓异常,空指针只不过是他的武器,但他杀戮过多,渐渐地人们只记住了空指针这三个字。
macrozheng
2020/12/21
7680
空指针的传说
空指针的传说
他原本不叫这个名字,空指针原本复姓异常,空指针只不过是他的武器,但他杀戮过多,渐渐地人们只记住了空指针这三个字。
艾小仙
2021/01/11
7260
空指针的传说
空类型指针
malloc 查看底层源码中发现是空类型的指针,空类型的指针可以接收任意类型的指针,但是不能取出指针里的内容,如果要取出内容必须要强转。
潇洒
2019/07/02
8060
空指针,野指针,万能指针
空指针指向地址编号为0的地址,不可以访问空指针指向的内容,因为内存地址编号0~255之间被系统占用,不可以访问 但是可以printf("%d",p);,输出p指向的地址
大忽悠爱学习
2021/03/02
1.4K0
C/CPP 指针变量 | 数组指针 | 指针数组 | 野指针 | 空指针
普通变量可以不赋初值,但是指针变量的初值必须万分慎重,因为未来的*操纵会以这个初值为目标内存地址,往里面读写数据(可以才C primer plus中看到相应分析)
CtrlX
2023/03/21
1.7K0
C/CPP 指针变量 | 数组指针 | 指针数组 | 野指针 | 空指针
C/CPP 指针变量 | 数组指针 | 指针数组 | 野指针 | 空指针
普通变量可以不赋初值,但是指针变量的初值必须万分慎重,因为未来的*操纵会以这个初值为目标内存地址,往里面读写数据(可以才C primer plus中看到相应分析)
CtrlX
2022/10/04
1.7K0
C/CPP 指针变量 | 数组指针 | 指针数组 | 野指针 | 空指针
dubbo 调用报Null 空指针 ,可能并不是真正的空指针
在消费consumer调用rpc的时候,传参明明不为空(已经打日志校验),但是,在rpc提供者的第57行代码,第一行,就报空指针。
MickyInvQ
2020/09/27
2.5K0
java空指针报错_空指针异常是什么意思
Java 中任何对象都有可能为空,当我们调用空对象的方法时就会抛出 NullPointerException 空指针异常,这是一种非常常见的错误类型。我们可以使用若干种方法来避免产生这类异常,使得我们的代码更为健壮。本文将列举这些解决方案,包括传统的空值检测、编程规范、以及使用现代 Java 语言引入的各类工具来作为辅助。
全栈程序员站长
2022/11/17
2.2K0
java空指针报错_空指针异常是什么意思
如何优雅的解决空指针?
在实际的系统运行过程中,难免会出现报NullPointerException空指针的错误,造成这样的本质原因就是数据或者对象为空,导致程序进一步执行的时候报错!
Java极客技术
2022/12/02
1.1K0
c专题之指针---野指针和空指针解析
在上一篇c专题指针文章中,我们介绍了什么是指针,文章里面从普通变量进而引出指针的概念,这样对指针的理解有一定的帮助(其实最好的理解,就是要明白硬件里面的内存原理,这是理解指针最好的地方,就好比说会汇编语言的人来去理解指针这里跟不会指针的人去理解,会有很大的差异的,在学汇编的时候,会接触到好多有关计算机里面内存的大话题,这个对于搞汇编的来说,掌握了汇编,对理解指针的原理非常容易;而大部分人(当然也包括我自己),刚开始学指针,是真的非常吃力,学了一阵子,感觉是学会了,但是一段时间没有去接触指针,再次来看指针的话,感觉一脸懵逼,好像没学过一样,不知道大家有没有我这样的经历,哈哈哈;这里指出不是鼓励大家去学花太多时间在汇编上(个人观点,现在出来上班,好少会搞汇编开发,你搞stm32和一些稍微功能强大的芯片,拿汇编去写,那简直不敢想象,而且也没听过谁这样干过),其实还是当你用到的时候再去学,很快上手的,就是有好多汇编指令要记,如果你一遍学一遍用,反而会学的更快,理解的更深,而且现在对理解一些高级芯片里面的启动代码会非常有帮助的)。好了,废话太多,来进入主题!
用户6280468
2022/03/18
1.8K0
c专题之指针---野指针和空指针解析
如何有效的避免空指针异常
空指针异常在新手程序员里面非常常见,不只是新手,所有初级、中级甚至是高级都不可避免。
甲蛙全栈
2021/01/22
1.9K0
Java解决空指针的神器Optional
Java 8 引入的一个很有趣的特性是 Optional 类。Optional 类主要解决的问题是臭名昭著的空指针异(NullPointerException) 。假设我们有两个类:
Jensen_97
2023/09/09
2520
Java解决空指针的神器Optional
实用避免空指针的工具类
一星陨落,黯淡不了星空灿烂;一花凋零,荒芜不了整个春天。——巴尔扎克 package com.ruben.utils; import com.ruben.pojo.User; import org.thymeleaf.expression.Lists; import sun.reflect.misc.ReflectUtil; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import
阿超
2022/08/16
4820
空指针赋值(指针赋值有几种方法)
上学期刚学C语言的时候很迷,老师说要避免野指针,但是空指针似乎又没办法赋值,就只好尽量减少指针的使用。 今天查了一下发现是这样赋值的: 先把要赋值的变量的地址赋给空指针,然后才能把变量的值赋给该指针。
全栈程序员站长
2022/08/01
1.4K0
SpringBoot 注入的@service为空,运行时报空指针
SpringBoot 注入的@service为空,运行时报空指针
Java架构师必看
2021/09/14
2.1K0
SpringBoot 注入的@service为空,运行时报空指针
对象实例化空指针处理
首先创建一个package包,将其Menu类及相关代码放入其中,并在该package包下创建另一个类MenuItem,然后通过构造函数,写入需要运行的对象信息,最后在Menu类中用new***()格式重新将对象实例化。相关代码及结果如下:
算法与编程之美
2023/08/22
1550
对象实例化空指针处理
jdbctemplate查询为空报错_java空指针异常举例
Dao类是不能直接new出来的必须是通过 ApplicationContext applicationContext= new
全栈程序员站长
2022/11/17
3.1K0
一个关于空指针的思考
其中int x= (char *)&((student *)0)->age - (char *)0这一行代码用于求age在结构体中的偏移量(结果是3),对main函数反汇编后的结果如下:
charlieroro
2020/03/24
4560
Collectors.toMap空指针问题
对于Collectors.toMap,我们使用时如果value为空,则会抛出空指针,因为底层调用的Map.merge函数
阿超
2022/08/17
8150

相似问题

strncat Wformat-使用gcc 8.2.1时的溢出警告

30

如何修复警告'sprintf‘,在目标的末尾写入终止nul [-Wformat-溢出=]

11

GCC编译器警告溢出

22

GCC指针抛出警告

33

在使用带空*参数的函数指针时抑制gcc警告

13
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文