标签: pointers

查找由智能指针引起的内存泄漏

有没有人知道发现智能指针引起的内存泄漏的"技术"?我目前正在开发一个用C++编写的大型项目,该项目大量使用带引用计数的智能指针.显然我们有一些由智能指针引起的内存泄漏,它们仍然在代码中的某处被引用,因此它们的内存不会被释放.很难找到带有"不必要"引用的代码行,导致相应的对象不被释放(尽管它不再使用).

我在网上找到了一些建议,建议收集参考计数器的递增/递减操作的调用堆栈.这给了我一个很好的提示,哪一段代码导致参考计数器增加或减少.

但我需要的是某种算法将相应的"增加/减少调用堆栈"组合在一起.在删除这些调用堆栈之后,我希望(至少)剩下一个"增加调用堆栈",它向我显示带有"不必要"引用的代码段,这导致相应的对象不被释放.现在修复泄漏没什么大不了的!

但有人想知道进行分组的"算法"吗?

开发在Windows XP下进行.

(我希望有人理解,我试图解释......)

EDIt:我说的是循环引用造成的泄漏.

c++ pointers memory-leaks smart-pointers

18
推荐指数
2
解决办法
9934
查看次数

dword ptr使用混乱

如果我们使用汇编语言

mov eax, dword ptr[ebx]
Run Code Online (Sandbox Code Playgroud)

那么它意味着复制ebx指向的值(ebx包含地址值,而不是实际值,此指令复制地址中的实际值)?

如果我们使用

mov eax, dword ptr[some_variable]
Run Code Online (Sandbox Code Playgroud)

那么它意味着将变量"some_variable"本身的值复制到eax,而不是复制变量"some_variable"指向的值?

我的理解是否正确?

如果是,我很困惑为什么相同的汇编指令有两种不同的含义 - 在第一种情况下有一个间接级别,但在第二种情况下没有额外的间接级别.

任何意见?

编辑:

并非每个[]都没有产生任何影响,例如,指令xchg将采用一个方向的水平,这将加载edx指向的值.

整个源代码可以从中找到,

http://www.codeproject.com/KB/threads/spinlocks.aspx

#ifdef WIN32
inline int CPP_SpinLock::TestAndSet(int* targetAddress, int nValue)
{
    __asm {
        mov edx, dword ptr [pTargetAddress]
        mov eax, nValue
        lock xchg eax, dword ptr [edx]
    }
}
#endif // WIN32
Run Code Online (Sandbox Code Playgroud)

x86 assembly pointers dword

18
推荐指数
1
解决办法
3万
查看次数

使用C中的指针的const用法

我正在讨论C并且对const使用指针有疑问.我理解以下代码:

const char *someArray
Run Code Online (Sandbox Code Playgroud)

这是定义指向char类型的指针,const修饰符意味着someArray不能更改存储的值.但是,以下是什么意思?

char * const array
Run Code Online (Sandbox Code Playgroud)

这是另一种指定参数的替代方法,该参数是指向名为"array" const且不能修改的数组的char指针吗?

最后,这个组合意味着什么:

const char * const s2
Run Code Online (Sandbox Code Playgroud)

作为参考,这些来自第7章中的Deitel C编程书,所有这些都用作传递给函数的参数.

c pointers const

18
推荐指数
4
解决办法
1万
查看次数

是否存储无效指针自动未定义的行为?

显然,取消引用无效指针会导致未定义的行为.但是如果只是在指针变量中存储无效的内存地址呢?

请考虑以下代码:

const char* str = "abcdef";
const char* begin = str;
if (begin - 1 < str) { /* ... do something ... */ }
Run Code Online (Sandbox Code Playgroud)

表达式begin - 1求值为无效的内存地址.请注意,我们实际上并没有取消引用此地址 - 我们只是在指针算法中使用它来测试它是否有效.尽管如此,我们仍然需要将无效的内存地址加载到寄存器中.

那么,这是不确定的行为吗?我从来没有想过,因为很多指针算法似乎依赖于这种事情,而指针实际上只是一个整数.但最近我听说即使将无效指针加载到寄存器中的行为也是未定义的行为,因为某些架构会自动抛出总线错误或者其他内容.任何人都可以向我指出C或C++标准的相关部分,无论哪种方式解决这个问题?

c c++ pointers

18
推荐指数
3
解决办法
1662
查看次数

C编译器可以生成一个64位的可执行文件,其中指针是32位吗?

大多数程序都适用于<4GB的地址空间,但需要使用x64架构上提供的新功能.

是否有编译器/平台,我可以使用x64寄存器和特定指令,但保留32位指针以节省内存?

是否可以透明地对遗留代码执行此操作?切换到底是做什么的?

要么

代码有什么变化,在保持32位指针的同时获得64位功能是必要的?

c 64-bit pointers compilation

18
推荐指数
3
解决办法
1957
查看次数

fopen()返回一个NULL指针,但该文件肯定存在

我的代码如下:

FILE *txt_file = fopen("data.txt", "r");
if (txt_file == NULL) {
    perror("Can't open file");
} 
Run Code Online (Sandbox Code Playgroud)

返回的错误消息是:

无法打开文件:没有这样的文件或目录

文件"的data.txt"肯定存在于工作目录(它存在于包含我的.c和.h文件的目录),所以为什么fopen()函数返回一个空指针?

c null fopen pointers visual-studio-2008

18
推荐指数
3
解决办法
5万
查看次数

如何在不知道类型的情况下声明模板指针?

这就是我想做的事情:

ExampleTemplate* pointer_to_template;
cin >> number;
switch (number) {
case 1:
    pointer_to_template = new ExampleTemplate<int>();
    break;
case 2:
    pointer_to_template = new ExampleTemplate<double>();
    break;
}
pointer_to_template->doStuff();
Run Code Online (Sandbox Code Playgroud)

这不会编译,因为在声明指针时必须指定模板类型.(ExampleTemplate* pointer_to_template应该是ExampleTemplate<int>* pointer_to_template.)不幸的是,我不知道模板的类型,直到它在switch块中声明.对于这种情况,最好的解决方法是什么?

c++ generics templates pointers

18
推荐指数
3
解决办法
1万
查看次数

Valgrind:大小为1的读数无效

我遇到了valgrind的问题:这是我的程序(错误出现的主要部分):

int main()
{
char comanda[N];
....
char *p;
while( fgets(comanda,100,stdin)!=NULL)
    {
    p=strtok(comanda," \n");
    if (strcmp(comanda,"INIT")==0)
        {
        p=strtok(NULL," ");
        Init(n);        
        }
395 >>if (strcmp(p,"DUMP")==0)
        {
        Dump(n);}
    if (strcmp(p,"ALLOC")==0)
        {
        Alloc(j,n);
        }
    ....return 0;}
Run Code Online (Sandbox Code Playgroud)

当我运行valgrind时,它说:

Invalid read of size 1
at 0x401569: main (:395)
Address 0x0 is not stack'd malloc'd or (recently) free'd
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚这个程序有什么问题.

c valgrind pointers

18
推荐指数
2
解决办法
5万
查看次数

传递函数指针

关于如何将指针传递给指针函数,我有点困惑.我有一个函数,它指向一个我理解没有问题的函数(ExecBlock).但是我给了另一个函数原型(ExecBlock2),它接受了解引用指针(我不确定它到底是什么),如果传递函数有任何参数,也会接受参数.如果有人可以解释优先级以及解释引用函数的确切内容.这不仅仅是传递函数本身吗?在这种情况下(void*)做什么?

int ExecBlock (void (*f) (void), int isSet)
{
    return ExecBlock2( HOW TO PASS HERE? , NULL, isSet);
}

int ExecBlock2(void *(*f)(void *), void *arg, int isSet)
{
    ... more code
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

c c++ pointers function parameter-passing

18
推荐指数
1
解决办法
7万
查看次数

粉碎堆栈example3 ala Aleph One

我在Linux x86_64上重现了Smashing the Stack for Fun and Profit的例子3 .但是,我无法理解应该递增到返回地址的正确字节数是多少,以便跳过指令:

0x0000000000400595 <+35>:   movl   $0x1,-0x4(%rbp)
Run Code Online (Sandbox Code Playgroud)

这是我认为x = 1指令的地方.我写了以下内容:

#include <stdio.h>

void fn(int a, int b, int c) {
  char buf1[5];
  char buf2[10];
  int *ret;

  ret = buf1 + 24;
  (*ret) += 7;
}

int main() {
  int x;

  x = 0;
  fn(1, 2, 3);
  x = 1;
  printf("%d\n", x);
}
Run Code Online (Sandbox Code Playgroud)

并在gdb中拆解它.我已禁用地址随机化并使用该-fno-stack-protector选项编译程序.

问题1

我可以从下面的反汇编输出中看到,我想跳过地址指令0x0000000000400595:返回地址callq <fn>movl指令地址.因此,如果返回地址是0x0000000000400595,并且下一条指令是0x000000000040059c,我应该在返回地址中添加7个字节?

0x0000000000400572 <+0>: …
Run Code Online (Sandbox Code Playgroud)

c security pointers stack-smash

18
推荐指数
1
解决办法
495
查看次数