std::string &func(int vlu)
{
std::string str;
str = std::to_string(vlu) + "something";
return str;
}
Run Code Online (Sandbox Code Playgroud)
上述功能明显不安全.
以下是另一个版本.
std::string &func(int vlu)
{
return std::to_string(vlu) + "something";
}
Run Code Online (Sandbox Code Playgroud)
我有一些问题:
第二个版本的编译器(gcc)没有给我任何警告.安全吗?我只是认为编译器(或其他什么?)将创建一个临时变量来保存表达式的返回std::to_string(vlu) + "something".所以第二个版本也不安全.我说对了?
在下面的代码中,为什么会s1.printVal导致悬空指针错误?是不是s1直到它的销毁的对象,即它的指针,仍然可以访问?
class Sample
{
public:
int *ptr;
Sample(int i)
{
ptr = new int(i);
}
~Sample()
{
delete ptr;
}
void PrintVal()
{
cout << "The value is " << *ptr;
}
};
void SomeFunc(Sample x)
{
cout << "Say i am in someFunc " << endl;
}
int main()
{
Sample s1 = 10;
SomeFunc(s1);
s1.PrintVal(); // dangling pointer
}
Run Code Online (Sandbox Code Playgroud)
我必须实现一个看起来像这样的函数:
MyList * sum (MyList * l1, MyList * l2) {
MyList * newlist = new MyList();
//Adds two objects and place the result in a third new list
return newlist;
}
Run Code Online (Sandbox Code Playgroud)
该函数采用了两个列表,并将每个对象的总和放入一个新列表中.所述MyList类曾与指针指向节点next可变的,并且该列表内的对象的用户定义被.
这让我思考 - 我该如何处理来自对象和列表本身的动态内存分配?因为我必须为新列表的每个对象创建内存.
有没有办法将对象总和的值放在新列表中而不必依赖动态分配?也许做这样的事情:
Object result(node1->content + node2->content);
Node->content = &result; // will this object be erased when the function ends?
Run Code Online (Sandbox Code Playgroud)
而不是这个:
Node->content = new Object(node1->content + node2->content);
Run Code Online (Sandbox Code Playgroud)
我应该如何处理函数内部创建的新列表的生命周期,该函数将在函数结束后保存内存的变量?返回新列表时,我可以这样做吗?
MyList & sum (MyList * l1, MyList * l2) {
//Create variable without allocating …Run Code Online (Sandbox Code Playgroud) c++ pointers memory-management dynamic-allocation dangling-pointer
我想,为什么他们有一个悬摆指针向别人解释和自由是如何工作(以及指针的值,因此是通过按值),但我认为我需要一种方法来打印指针与工作不" t"不确定"(如同printf("%p", ptr)).
memcpy会不会这样做?
char buf1[sizeof(char *)];
char buf2[sizeof(char *)];
char *malloced = malloc(10);
memcpy(buf1, &malloced, sizeof(char *));
free(malloced);
memcpy(buf2, &malloced, sizeof(char *));
for (int i=0; i<sizeof(char *); i++) {
printf("%hhd %hhd / ", buf1[i], buf2[i]);
}
Run Code Online (Sandbox Code Playgroud) 我已阅读如何在 Xcode Instruments 中演示内存泄漏和僵尸对象?但这是针对 Objective-c 的。这些步骤不适用。
通过阅读这里,我了解到僵尸是以下物体:
不太确定这与访问已释放的对象有何不同。
我的意思是在 Swift 中你可以这样做:
var person : Person? = Person(name: "John")
person = nil
print(person!.name)
Run Code Online (Sandbox Code Playgroud)
人员被解除分配了吗?是的!
我们是否试图指出这一点?是的!
那么有人可以分享导致创建悬空指针的最常见错误吗?
t在为值赋值之前,是否必须在以下代码中进行初始化t?代码是否正确?
void swap(int *x, int *y)
{
int *t;
*t = *x;
*x = *y;
*y = *t;
}
Run Code Online (Sandbox Code Playgroud) 在堆栈中,保留了内存main,我们称之为main函数的堆栈帧.
当我们调用该Add函数时,内存保留在堆栈顶部.在Add函数的堆栈帧,a并且b是本地指针和c是计算的整数,然后我们返回参考.c是Add函数的局部变量.
现在当Add函数执行完成时,堆栈中的内存空间也被释放,所以当我们尝试在mainwith指针中访问这个地址时p,我们试图访问的内容基本上是一个释放空间.编译器发出警告,但为什么它仍然正确打印值5?
答案可能是机器没有释放内存空间,因为它没有必要,因为没有更多的功能.但是如果我们编写另一个函数,Hello那么它肯定应该释放Add调用堆栈中的函数空间,但程序仍会打印
Yay 5
Run Code Online (Sandbox Code Playgroud)
是因为像在堆中我们需要null在释放它之后指定一个指针,否则我们仍然可以访问它?有类似的东西吗?
/* void Hello()
{
printf("Yay");
} */
int* Add(int *a,int *b)
{
int c=*a+*b;
return &c;
}
int main()
{
int a=1,b=4;
int *p=Add(&a,&b);
// Hello();
printf("\t%d",*p);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我是C++的新手,想问下面的代码是否是悬空指针或内存泄漏的一个例子,因为它指向动态分配的数组:
int * n = new int[10];
for (int prev = 0; prev < 10; prev++) {
*n = *(n + prev + 1);
}
delete[] n;
n = nullptr;
Run Code Online (Sandbox Code Playgroud) 根据一篇文章(这里和那里),这段代码是一个错误的使用后免费示例:
#include <iostream>
#include <string>
#include <string_view>
int main() {
std::string s = "Hellooooooooooooooo ";
std::string_view sv = s + "World\n";
std::cout << sv;
}
Run Code Online (Sandbox Code Playgroud)
文章中说使用strings 时将释放 s string_view!这与我的调试经验背道而驰。但我要求您确认/验证/检查这一点。
根据我的经验,堆栈/范围变量在范围退出时被释放(调用析构函数将是更正确的措辞)。这意味着在这种情况下,这将发生在std::cout << sv;
但是我从来没有使用过string_view,所以我不知道这个对象的任何内部机制。
如果确实是危险行为,您能解释一下吗?否则,我很高兴阅读确认范围变量析构函数仅在当前范围的退出时被调用,自然地,或者在抛出异常时,中断当前范围内的线程。
编辑:在前两个答案之后,它确实是一个使用后免费使用。
附属问题:你认为我们可以在string_view的定义中添加一个带有delete关键字的移动构造函数来禁止吗?
我认为 VS2019 建议会创建一个悬空的参考情况,但我对其进行了测试,它似乎有效。这里发生了什么?
template<typename MessageType>
class Queue {
inline static std::vector<MessageType> messages;
public:
static bool isEmpty() {
return messages.size() == 0;
}
template <typename... Args>
static void emplace(Args&&... args) {
messages.emplace_back(std::forward<Args>(args)...);
}
static MessageType pop() {
auto const& val = messages.back();
messages.pop_back();
return val;
}
};
Run Code Online (Sandbox Code Playgroud)
看起来最后一条消息存活的时间足够长,可以复制到返回值中。这是好的做法吗?
dangling-pointer ×10
c++ ×7
c ×3
pointers ×3
c++11 ×2
reference ×2
gcc ×1
memory-leaks ×1
nszombie ×1
swift ×1