模板,结构和无效指针 - 哪里出错了 [英] Templates, Structs and Invalid Pointers - where did it go wrong

查看:44
本文介绍了模板,结构和无效指针 - 哪里出错了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我正在开展一个项目,在那里我遇到了一个问题:

程序核心并报告free():无效指针。

我发现解决方案,但不完全理解为什么首先发生

问题。


项目使用一个简单的模板类来完成作为一个缓冲区。

最初它有一个固定的长度,但如果有必要,它的附加方法将扩展

缓冲区的大小。


另一个类定义一个struct,它包含这个模板类作为

成员。在一个函数中,结构被创建,但是当它结束时,程序核心的范围是



检查核心它看起来是免费的模板类

析构函数导致核心。当我使用

调试器跟踪代码时,我发现在模板类构造函数退出后,其成员之一指向的

地址会发生变化。 br />

无论如何,我已经在下面添加了一个简化版本的代码

。我发现解决方法是修改结构,以便

引用模板类。

------ VarBuf Class< VarBuf.h- -----

#ifndef __TVARBUF_H__

#define __TVARBUF_H__


#include< stddef.h>

#include< string.h>

#include< stdlib.h>


模板< size_t Nclass TVarBuf

{

public:

TVarBuf(const char * initStr);

~TVarBuf();

private:

char m_Buf [N + 1];

char * m_Str;

size_t m_Capacity;

size_t m_Length;

};

#endif


模板< size_t N>

TVarBuf< ; N> :: TVarBuf(const char * initStr):

m_Str(NULL),

m_Capacity(N),

m_Length(0 )

{

m_Str = m_Buf;

m_Str [0] =''\ 0'';

}


模板< size_t N>

TVar Buf< N> ::〜TVarBuf()

{

if(m_Str!= m_Buf)

{

免费(m_Str);

}

}


-------------- -------------------


----主要应用< main.cpp -----


1 #include" VarBuf.h"

2 #include" stdio.h"

3 #include" time。 h"


4 typedef TVarBuf< 6ProfKey; //为我们的模板创建一个typedef

class


5 typedef struct

6 {

7 time_t m_CurrTime;

8 int m_Docs;

9 int m_OldDocs;

10 ProfKey m_OldestProfUrl; //这是模板类

11}教授;

12

13 int main(int argc,char ** argv)

14 {

15 {

16 time_t now = time(NULL);

17 Prof profile = {now, 0,0,NULL};

18} //应用程序核心离开此处后,配置文件

对象超出范围

19返回0;

20}


------------------------- -----------------


用以下命令编译上面的代码

g ++ -g -Wall -omain main.cpp


并运行主二进制结果:

free():无效指针0xbfffd66c!


我稍微修改了代码,以便主要的第10行读取:

-------------------------- ---------------------

ProfKey& m_OldestProfUrl; //参考ProfKey

----------------------------------- ------------

和第17行现在读取

----------------- -------------------------------

ProfKey键(NULL);

Prof profile = {now,0,0,key}

--------------------------- ---------------------


任何关于这里发生什么的解释都会很好。

解决方案

DaveJ写道:

[...]


>

另一个类定义一个结构,它包含这个模板类作为

成员。在一个函数中创建了struct,但是当它结束时,程序核心的范围是



它不是核心我(不幸的是)


检查核心它出现了模板类中的免费调用

析构函数导致了核心。当我用
跟踪代码时



这里有一个更小的例子来说明你正在做什么:


int main ()

{

int a = 5;

int * b =& a;

免费( b);

}


debugger我发现在模板类构造函数退出后,

表示其成员之一指向其更改。


无论如何,我已经包含了一个简化版本的代码

下面。我发现解决方法是修改结构,以便

获取对模板类的引用。



我想你已经不在了运气。你不能做什么。


>

------ VarBuf Class< VarBuf.h --- ---

#ifndef __TVARBUF_H__

#define __TVARBUF_H__


#include< stddef.h>

#include< string.h>

#include< stdlib.h>



这些是c标头。应该是:

#include< cstddef>

#include< cstring>

#include< cstdlib>
< blockquote class =post_quotes>
>

模板< size_t Nclass TVarBuf

{

public:

TVarBuf(const char * initStr);

~TVarBuf();

private:

char m_Buf [N + 1];

char * m_Str;

size_t m_Capacity;

size_t m_Length;

};

#endif


模板< size_t N>

TVarBuf< N> :: TVarBuf(const char * initStr):



initStr未使用


m_Str(NULL),

m_Capacity(N),
m_Length(0)

{

m_Str = m_Buf;

m_Str [0] =''\''' ;

}


模板< size_t N>

TVarBuf< N> ::〜TVarBuf()

{

if(m_Str!= m_Buf)



应该是

if(m_Str!=& ; m_Buf [0])


{

free(m_Str);



你在哪里分配这个内存?


}

}


---------------------------------


----主应用程序< main.cpp -----


1 #include" VarBuf.h"

2 #includestdio.h

3 #include" time.h"



不要在c ++程序中使用c头


>

4 typedef TVarBuf< 6ProfKey; //为我们的模板创建一个typedef

class



这个typedef看起来非常C-ish


5 typedef struct

6 {

7 time_t m_CurrTime;

8 int m_Docs;

9 int m_OldDocs;

10 ProfKey m_OldestProfUrl; //这是模板类

11}教授;

12

13 int main(int argc,char ** argv)

14 {

15 {

16 time_t now = time(NULL);

17 Prof profile = {now, 0,0,NULL};

18} //应用程序核心离开此处后,配置文件

对象超出范围

19返回0;

20}


------------------------- -----------------


用以下命令编译上面的代码

g ++ -g -Wall -omain main.cpp


并运行主二进制结果:

free():无效指针0xbfffd66c!


我稍微修改了代码,以便主要的第10行读取:

-------------------------- ---------------------

ProfKey& m_OldestProfUrl; //参考ProfKey

----------------------------------- ------------

和第17行现在读取

----------------- -------------------------------

ProfKey键(NULL);

Prof profile = {now,0,0,key}

--------------------------- ---------------------



这并没有解决你的问题,这是在TVarBuf课程





8月28日上午10点36分,anon< a ... @ no.nowrote:


DaveJ写道:


initStr未使用



我已经缩小了VarBuf.h的大小,因为实际的班级相当于b $ b大。真正的类确实使用initStr,但在我的情况下它应该

总是为NULL。


m_Str(NULL),

m_Capacity(N),

m_Length(0)

{

m_Str = m_Buf;

m_Str [0] =''\ 0'';

}



我认为问题在于重新分配m_Str。


在构造函数中m_Str = m_Buf;似乎很好。

构造函数存在后,m_Str指向的地址突然变为

更改。


5 typedef struct

6 {

7 time_t m_CurrTime;

8 int m_Docs;

9 int m_OldDocs;

10 ProfKey m_OldestProfUrl; //这是模板类

11} Prof;

12



仅此如果我从一个结构中创建VarBuf(带有或没有typedef的
),就会发生这种情况。如果我在方法中直接创建它就没有问题。


有趣的是,你说它并不是你的核心。最初这个

是在一个程序中运行RedHat3多年没有问题。当我们将它移到RH5时,核心开始出现(虽然我现在已经能够在某些RH3机器上复制它了。)


DaveJ写道:


>> m_Str(NULL),
m_Capacity(N),
m_Length(0)
{
m_Str = m_Buf;



应该是:

m_Str =& m_Buf [0];


>> m_Str [0] =''\ 0'';
}



我认为问题在于重新分配m_Str 。


在构造函数中m_Str = m_Buf;似乎很好。

构造函数存在后,m_Str指向的地址突然变为

更改。



对不起我错过了某种方式。无论如何,它应该工作正常。


>


>> 5 typedef struct
6 {
7 time_t m_CurrTime;
8 int m_Docs;
9 int m_OldDocs;
10 ProfKey m_OldestProfUrl; //这是模板类
11}教授;
12



只有从内部创建VarBuf才会出现这种情况一个struct(带有或

没有typedef)。如果我在方法中直接创建它就没有问题。


有趣的是,你说它并不是你的核心。最初这个

是在一个程序中运行RedHat3多年没有问题。当我们将它移到RH5时,核心开始出现(虽然我现在已经能够在某些RH3机器上复制它了。)



RH3 ??哇你用的是什么编译器?

我在RH8上用gcc 4.1.3编译了你的例子,它运行正常。


尝试运行你的真实程序(或者你的例子)用valgrind看看

有什么问题


Recently I was working on a project where I came across an issue where
the program cored and reported "free(): invalid pointer".
I found a resolution for this, but don''t fully understand why the
issue occurred in the first place.

The project uses a simple template class that acts as a buffer.
Initially it has a fixed length, but it''s append methods will extend
the size of the buffer if necessary.

Another class defines a struct, that contains this template class as a
member. In one function the struct is created, but when it goes out
of scope the program cores.

Examining the core it appears a call to free in the template classes
destructor caused the core. When I traced through the code with the
debugger I found that after the template class constructor exits, the
address that one of its member''s points to changes.

Anyway I''ve included a cut down and simplified version of the code
below. I found the resolution was to modify the struct so that it
takes a reference to the template class.
------ VarBuf Class <VarBuf.h------
#ifndef __TVARBUF_H__
#define __TVARBUF_H__

#include <stddef.h>
#include <string.h>
#include <stdlib.h>

template<size_t Nclass TVarBuf
{
public:
TVarBuf (const char *initStr);
~TVarBuf ();
private:
char m_Buf[N + 1];
char* m_Str;
size_t m_Capacity;
size_t m_Length;
};
#endif

template<size_t N>
TVarBuf<N>::TVarBuf(const char *initStr) :
m_Str(NULL),
m_Capacity(N),
m_Length(0)
{
m_Str = m_Buf;
m_Str[0] = ''\0'';
}

template<size_t N>
TVarBuf<N>::~TVarBuf()
{
if(m_Str != m_Buf)
{
free(m_Str);
}
}

---------------------------------

---- Main App <main.cpp-----

1 #include "VarBuf.h"
2 #include "stdio.h"
3 #include "time.h"

4 typedef TVarBuf<6ProfKey; // Create a typedef for our template
class

5 typedef struct
6 {
7 time_t m_CurrTime;
8 int m_Docs;
9 int m_OldDocs;
10 ProfKey m_OldestProfUrl; // this is the template class
11 } Prof;
12
13 int main(int argc, char** argv)
14 {
15 {
16 time_t now = time(NULL);
17 Prof profile = {now, 0, 0, NULL};
18 } // Application cores after it leaves here and the profile
object goes out of scope
19 return 0;
20 }

------------------------------------------

Compiling the above code with the following command
g++ -g -Wall -omain main.cpp

and running the main binary results in:
free(): invalid pointer 0xbfffd66c!

I modified the code slightly so that line 10 of main reads:
-----------------------------------------------
ProfKey& m_OldestProfUrl; //take a reference to ProfKey
-----------------------------------------------
and line 17 now reads
------------------------------------------------
ProfKey key(NULL);
Prof profile = {now, 0, 0, key}
------------------------------------------------

Any explanation of whats going on here would be good.

解决方案

DaveJ wrote:
[...]

>
Another class defines a struct, that contains this template class as a
member. In one function the struct is created, but when it goes out
of scope the program cores.

It doesn''t core for me (unfortunately)

Examining the core it appears a call to free in the template classes
destructor caused the core. When I traced through the code with the

Here is even smaller example producing exactly what you are doing:

int main()
{
int a = 5;
int *b = &a;
free( b );
}

debugger I found that after the template class constructor exits, the
address that one of its member''s points to changes.

Anyway I''ve included a cut down and simplified version of the code
below. I found the resolution was to modify the struct so that it
takes a reference to the template class.

I guess you are out of luck. What you are doing is not allowed.

>
------ VarBuf Class <VarBuf.h------
#ifndef __TVARBUF_H__
#define __TVARBUF_H__

#include <stddef.h>
#include <string.h>
#include <stdlib.h>

These are c headers. Should be:
#include <cstddef>
#include <cstring>
#include <cstdlib>

>
template<size_t Nclass TVarBuf
{
public:
TVarBuf (const char *initStr);
~TVarBuf ();
private:
char m_Buf[N + 1];
char* m_Str;
size_t m_Capacity;
size_t m_Length;
};
#endif

template<size_t N>
TVarBuf<N>::TVarBuf(const char *initStr) :


initStr is not used

m_Str(NULL),
m_Capacity(N),
m_Length(0)
{
m_Str = m_Buf;
m_Str[0] = ''\0'';
}

template<size_t N>
TVarBuf<N>::~TVarBuf()
{
if(m_Str != m_Buf)

should be
if (m_Str != &m_Buf[0])

{
free(m_Str);

Where do you allocate this memory?

}
}

---------------------------------

---- Main App <main.cpp-----

1 #include "VarBuf.h"
2 #include "stdio.h"
3 #include "time.h"

Do not use c headers in a c++ program

>
4 typedef TVarBuf<6ProfKey; // Create a typedef for our template
class

This typedef looks very C-ish

5 typedef struct
6 {
7 time_t m_CurrTime;
8 int m_Docs;
9 int m_OldDocs;
10 ProfKey m_OldestProfUrl; // this is the template class
11 } Prof;
12
13 int main(int argc, char** argv)
14 {
15 {
16 time_t now = time(NULL);
17 Prof profile = {now, 0, 0, NULL};
18 } // Application cores after it leaves here and the profile
object goes out of scope
19 return 0;
20 }

------------------------------------------

Compiling the above code with the following command
g++ -g -Wall -omain main.cpp

and running the main binary results in:
free(): invalid pointer 0xbfffd66c!

I modified the code slightly so that line 10 of main reads:
-----------------------------------------------
ProfKey& m_OldestProfUrl; //take a reference to ProfKey
-----------------------------------------------
and line 17 now reads
------------------------------------------------
ProfKey key(NULL);
Prof profile = {now, 0, 0, key}
------------------------------------------------

This doesn''t solve your problem, which is in the TVarBuf class




On Aug 28, 10:36 am, anon <a...@no.nowrote:

DaveJ wrote:

initStr is not used

I''ve reduced the size of VarBuf.h as the actual class is fairly
large. The real class does use the initStr, but in my case it should
always be NULL.

m_Str(NULL),
m_Capacity(N),
m_Length(0)
{
m_Str = m_Buf;
m_Str[0] = ''\0'';
}

I think the issue lies around the re-assignment of m_Str.

In the constructor m_Str = m_Buf; seems fine.
After the constructor exists the address that m_Str points to suddenly
changes.

5 typedef struct
6 {
7 time_t m_CurrTime;
8 int m_Docs;
9 int m_OldDocs;
10 ProfKey m_OldestProfUrl; // this is the template class
11 } Prof;
12

This only occurs if I create the VarBuf from within a struct (with or
without the typedef). If I create it directly in the method there is
no problem.

It''s interesting that you say it didn''t core for you. Initially this
was in a program which ran on RedHat3 for years without issue. When
we moved it to RH5 the core started occurring (although I have now
been able to replicate it on some RH3 machines).


DaveJ wrote:

>> m_Str(NULL),
m_Capacity(N),
m_Length(0)
{
m_Str = m_Buf;

should be:
m_Str = &m_Buf[0];

>> m_Str[0] = ''\0'';
}


I think the issue lies around the re-assignment of m_Str.

In the constructor m_Str = m_Buf; seems fine.
After the constructor exists the address that m_Str points to suddenly
changes.

Sorry I missed that somehow. Anyway, like that it should work fine.

>

>>5 typedef struct
6 {
7 time_t m_CurrTime;
8 int m_Docs;
9 int m_OldDocs;
10 ProfKey m_OldestProfUrl; // this is the template class
11 } Prof;
12


This only occurs if I create the VarBuf from within a struct (with or
without the typedef). If I create it directly in the method there is
no problem.

It''s interesting that you say it didn''t core for you. Initially this
was in a program which ran on RedHat3 for years without issue. When
we moved it to RH5 the core started occurring (although I have now
been able to replicate it on some RH3 machines).

RH3?? wow what compiler are you using?
I compiled your example on RH8, with gcc 4.1.3 and it works fine.

Try running your real program (or your example) with valgrind and see
what is the problem


这篇关于模板,结构和无效指针 - 哪里出错了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆