动态结构 [英] Dynamic Structures

查看:69
本文介绍了动态结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我是C ++的新手,在我坐在我的

无聊的日常工作时试图自我教导(我以为我会把在我被指控之前,我已经被指责

作弊我的作业,即时45 ... ...


无论如何,我正在尝试动态分配一个结构,而我从

a文件中读取,但我的程序崩溃了,我不知道为什么除了那个

与我的内存操作使用new和delete。
<我非常擅长C所以学习的原因是我可以真实地将b / C ++放在我的简历而不仅仅是C ...而且我对此感兴趣

对象orrientated方面。


我可以使用类而不是结构吗?什么是最好的?我在哪里

出错?


谢谢


继承我的代码 -

#include< iostream>

#include< fstream>

#include< string>


使用命名空间std;


struct TOKEN

{

string linetoken;

};


int main()

{


TOKEN *代币;


int counter = 0;

ifstream ifs(" data.txt");

string line;


while (getline(ifs,line))

{


Tokens = new TOKEN [counter + 1];


标记[counter] .linetoken = line;


// cout<< [ << line<< " ]" << endl;

cout<<令牌[计数器] .linetoken<< endl;

counter = counter + 1;

}


cout<< AAAAAAAA;


删除代币;

返回0;

}

解决方案

< go ************* @ hotmail.comwrote in message

news:11 ** ********************@m73g2000cwd.googlegr oups.com ...


无论如何我''当我从

a文件中读取时,我试图动态分配一个结构,但是我的程序崩溃了,



崩溃前它能走多远?它是否显示AAAAAA第一个?


我不知道为什么除了那个

它与我的内存操作使用new和delete。


我可以使用类而不是结构吗?什么是最好的?我在哪里

出错了?



你可以用一个你可以用结构做的任何东西做什么,然后用副词
$ b $反之亦然。不同之处在于默认的可见性(类为私有,public为结构的
)。


#include< iostream>

#include< fstream>

#include< string>


使用命名空间std;


struct TOKEN



我不会那么大写。 (但你的风格!=我的风格。)


{

string linetoken;

};


int main()

{


TOKEN *代币;


int counter = 0;

ifstream ifs(" data.txt");

string line;


while( getline(ifs,line))

{


Tokens = new TOKEN [counter + 1];



new []类似于malloc(),而不是realloc()。你正在通过这个循环超过第一个时间泄漏内存,因为你丢失了记忆代币

用来指向。


这就是为什么在C ++中通常使用容器类。它会更好

更容易使用std :: vector< TOKENhere,然后你就可以做

token.push_back(TOKEN(counter + 1));每次循环都没有

来担心内存分配。


另一方面,如果你这样做是为了自己做一个练习

动态内存管理,也许你应该创建自己的容器

类。称它为TokenContainer,TokenList或TokenArray,并且

提供了一种在末尾添加新标记的方法,另一种方法是从中获取值

。您可以将其实现为可调整大小的数组,或链接列表,或者以您喜欢的任何其他方式实现
。专注于速度的正确性。确保你的
析构函数干净地删除容器中的所有内容。使用内存泄漏

探测器(如valgrind)来检查你是否确实删除了所有东西。


一旦你创建了你的TokenContainer并使其正常工作,抛弃它

并使用std :: vector,std :: deque或std :: list。它们可能比你的容器稳定得多,而且速度要快得多。


Tokens [counter] .linetoken = line ;


// cout<< [ << line<< " ]" << endl;

cout<<令牌[计数器] .linetoken<< endl;

counter = counter + 1;

}


cout<< AAAAAAAA;


删除令牌;



错误的运营商。这应该是:

delete [] Tokens;

因为你用new来创建一个数组而不是一个对象。这可能是导致崩溃的原因。


返回0;

}


< go ************* @ hotmail.comschrieb im Newsbeitrag

news:11 *** *******************@m73g2000cwd.googlegr oups.com ...





我是C ++的新手,当我坐在我的

无聊的日常工作中时,我试图自我教导(我想在我被指控之前把它放到一边) >
作弊我的作业,即时45 ...)


无论如何我想在我读取时动态分配结构

a文件,但我的程序崩溃了,我不确定为什么除了那个

与我的内存操作使用new和delete。


Im相当擅长C所以学习的原因是我可以真实地将b / C ++放在我的简历而不仅仅是C ...而且我对
$ b $感兴趣b obj等等方面。


我可以使用类而不是结构吗?什么是最好的?我在哪里

出错?


谢谢


继承我的代码 -

#include< iostream>

#include< fstream>

#include< string>


使用命名空间std;


struct TOKEN



不要仅使用带大写字母的标识符。这些名称应该更好地保留用于#define''d宏的标识符。


{

string linetoken;

};


int main()

{


TOKEN *代币;



你应该总是初始化你的变量,特别是指针。


int counter = 0;



为什么你用大写字母T写代币但用小写字母代表

c?尝试找到一致的命名约定。如果你不必记住以大写字母开头的名字

以及带小写字母的名字,那么它会让生活变得轻松多了。


ifstream ifs(" data.txt");

string line;


while(getline(ifs,line))

{


Tokens = new TOKEN [counter + 1];



这会创建一个计数器+ 1个TOKEN数组,并将数组中的第一个元素的地址分配给Tokens。最初它只用一个元素分配一个带有

的数组,并将其地址分配给Tokens,覆盖Tokens的

未定义值。到目前为止没有错。


在下一次运行中,它分配一个包含2个元素的NEW数组,并将第一个元素的

地址分配给Tokens,覆盖令牌的旧值,

在前一次循环中分配的数组。这导致了内存泄漏中的
,循环中的每一轮都有一个,除了第一个

之外。


代币[counter] .linetoken = line;



这将行的内容存储在新分配的

数组的最后一个元素中。数组的所有其他元素都将包含默认值,在这种情况下为空

字符串。


// cout<< [ << line<< " ]" << endl;

cout<<令牌[计数器] .linetoken<< endl;

counter = counter + 1;

}


cout<< AAAAAAAA;


删除令牌;



这会导致未定义的行为。你只能删除你从

new中获得的东西。如果您使用new []来分配内存,则必须使用delete []再次释放



返回0; < br $>
}



你必须分配一个足够大的数组来保存

advance中的所有行。仅仅因为你在每个循环中分配较大的地址并将它们的

地址分配给同一个变量,不会将之前的

数组的内容复制到新的数组中。如果你发现,你的阵列不够大,

你必须创建一个新的,更大的阵列,将旧的

数组中的所有现有数据复制到新的,最后删除[]旧的数组,然后用新数组的地址覆盖

的地址。


或者你最好先了解像std :: list或std :: vector。它们更容易使用,然后使用new [] / delete []分配的C样式数组。

将此与您的代码进行比较:


int main()

{

std :: vector< TOKENtokens;

std :: ifstream ifs(" data。 txt");

std :: string line;

while(std :: getline(ifs,line))

{

tokens.push_back(line);

std :: cout<< tokens.back()。linetoken<< std :: endl;

}

std :: cout<< tokens.size()<< "行阅读 << std :: endl;

}


HTH

亨氏


go*************@hotmail.com 写道:


继承我的代码 -


#include< iostream>

#include< fstream>

#include< string>



我建议还包括< ostream>,因为你使用的是endl。稍后在您的

代码中。包括< iostreamand /或< fstreamdoes不保证使得endl

可用。或者,如果您不需要同时刷新输出,而不是使用endl来显示换行符,您可以只输出'b $ b输出''\ n''。


Hi,

Im new to C++ and trying to self teach myself whilst I sit at my
unentertaining day job (thought i''d put that across before im accused
of cheating on my homework, im 45...)

Anyway I''m trying to dynamically assign a structure whilst I read from
a file, however my program crashes, and im not sure why other than that
its to do with my memory operations using new and delete.

Im pretty good at C so the reason for learning is so that I can truely
put C/C++ on my CV instead of just C... but also im interested in the
object orrientated aspect.

Could I use a class instead of a structure? whats best? where am I
going wrong?

Thanks

Heres my Code -

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct TOKEN
{
string linetoken;
};

int main()
{

TOKEN *Tokens;

int counter = 0;
ifstream ifs("data.txt");
string line;

while(getline(ifs,line))
{

Tokens = new TOKEN[counter + 1];

Tokens[counter].linetoken = line;

//cout << "[ " << line << " ]" << endl;
cout << Tokens[counter].linetoken << endl;
counter = counter + 1;
}

cout << "AAAAAAAA";

delete Tokens;
return 0;
}

解决方案

<go*************@hotmail.comwrote in message
news:11**********************@m73g2000cwd.googlegr oups.com...

Anyway I''m trying to dynamically assign a structure whilst I read from
a file, however my program crashes,

How far does it get before crashing? Does it display "AAAAAA" first?

and im not sure why other than that
its to do with my memory operations using new and delete.

Could I use a class instead of a structure? whats best? where am I
going wrong?

Anything you can do with a class you can do with a structure, and vice
versa. The difference is the default visibility (private for class, public
for struct).

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct TOKEN

I wouldn''t have made that uppercase. (But your style != my style.)

{
string linetoken;
};

int main()
{

TOKEN *Tokens;

int counter = 0;
ifstream ifs("data.txt");
string line;

while(getline(ifs,line))
{

Tokens = new TOKEN[counter + 1];

new[] is analogous to malloc(), not to realloc(). You''re leaking memory each
time through this loop beyond the first, because you lose the memory Tokens
used to point at.

This is why in C++ container classes are usually used instead. It''d be much
easier to use a std::vector<TOKENhere, then you could just do
token.push_back(TOKEN(counter + 1)); each time round the loop and not have
to worry about memory allocation.

On the other hand, if you are doing this as an excercise for yourself in
dynamic memory management, perhaps you should create your own container
class. Call it something like TokenContainer, TokenList or TokenArray and
provide a method to add a new token on the end, and another to get values
from it. You can implement it as a resizable array, or as a linked list, or
in any other way you like. Focus on correctness over speed. Make sure your
destructor deletes everything in the container cleanly. Use a memory leak
detector (such as valgrind) to check if you really did delete everything.

Once you have created your TokenContainer and got it working, throw it away
and use std::vector, std::deque or std::list. They''re likely to be much more
stable and much faster than your container :)

Tokens[counter].linetoken = line;

//cout << "[ " << line << " ]" << endl;
cout << Tokens[counter].linetoken << endl;
counter = counter + 1;
}

cout << "AAAAAAAA";

delete Tokens;

Wrong operator. This should be:
delete[] Tokens;
since you used new to create an array instead of a single object. This is
possibly the cause of the crash.

return 0;
}


<go*************@hotmail.comschrieb im Newsbeitrag
news:11**********************@m73g2000cwd.googlegr oups.com...

Hi,

Im new to C++ and trying to self teach myself whilst I sit at my
unentertaining day job (thought i''d put that across before im accused
of cheating on my homework, im 45...)

Anyway I''m trying to dynamically assign a structure whilst I read from
a file, however my program crashes, and im not sure why other than that
its to do with my memory operations using new and delete.

Im pretty good at C so the reason for learning is so that I can truely
put C/C++ on my CV instead of just C... but also im interested in the
object orrientated aspect.

Could I use a class instead of a structure? whats best? where am I
going wrong?

Thanks

Heres my Code -

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct TOKEN

Don''t use identifiers with upper-case letters only. Those names should
better be reserved for identifiers used for #define''d macros.

{
string linetoken;
};

int main()
{

TOKEN *Tokens;

You should always initialize your variables, especially pointers.

int counter = 0;

Why do you write Tokens with an upper-case T but counter with a lower-case
c? Try to find a consistent naming convention. It makes life a lot easier if
you don''t have to remember which name to start with an upper-case letter
andwhich one with a lower-case letter.

ifstream ifs("data.txt");
string line;

while(getline(ifs,line))
{

Tokens = new TOKEN[counter + 1];

This creates an array of counter+1 TOKENs and assigns the address of the
first element in the array to Tokens. Initially it allocates an array with
just one element and assigns its address to Tokens, overwritting Tokens''s
undefined value. Nothing wrong so far.

On the next run, it allocates a NEW array with 2 elements and assigns the
address of the first element to Tokens, overwriting the old value of Tokens,
the array allocated during the previous pass through the loop. That results
in a memory leak, one in every round through the loop, except for the first
one.

Tokens[counter].linetoken = line;

This stores the contents of line in the last element of the newly allocated
array. All other elements of the array will contain default values, empty
strings in this case.

//cout << "[ " << line << " ]" << endl;
cout << Tokens[counter].linetoken << endl;
counter = counter + 1;
}

cout << "AAAAAAAA";

delete Tokens;

This causes undefined behaviour. You must only delete something you got from
new. If you used new[] to allocate memory, you have to use delete[] to free
it again.

return 0;
}

You have to allocate one array large enough to hold all the lines in
advance. Just because you allocate larger ones in each loop and assign their
address to the same variable, does not copy the contents of the previous
array to the new one. If you find out, that your array isn''t large enough,
you have to create a new, larger one, copy all existing data from the old
array to the new one and finally delete[] the old array before you overwrite
its address with that of the new array.

Or you better learn about containes like std::list or std::vector. They are
much easier to use then C style arrays allocated with new[]/delete[].
Compare this with your code:

int main()
{
std::vector<TOKENtokens;
std::ifstream ifs("data.txt");
std::string line;
while (std::getline(ifs, line))
{
tokens.push_back(line);
std::cout << tokens.back().linetoken << std::endl;
}
std::cout << tokens.size() << " lines read" << std::endl;
}

HTH
Heinz


go*************@hotmail.com wrote:

Heres my Code -

#include <iostream>
#include <fstream>
#include <string>

I recommend to also include <ostream>, because you use "endl" later in your
code. Including <iostreamand/or <fstreamdoes not guarantee to make endl
available. Or, instead of using endl to display a newline you could just
output ''\n'', if you do not need to flush the output at the same time.


这篇关于动态结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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