注册 登录
编程论坛 C++教室

关于动态数组的问题

小糊涂神c30 发布于 2012-07-25 20:55, 908 次点击
比如要向一个数组中存放一个字符串,但字符串的长度并不知道,可能很长,有几百个那么长,也可能很短只有几个!如果数组申请的太长,造成内存浪费,如果太短又造成内存泄露,现在想用new和delete来动态的申请内存和释放内存,最好能重复的申请内存!
我的思想是
1.首先用new 申请内存空间,并通过返回值返回所开辟空间的地址,并用指针接收,此指针就相当于数组名。
2.使用此数组,进行字符串的赋值。
3.当数组空间满的时候再按1中的方法在次申请空间,并把上一次空间的内容复制到新的空间中,然后释放上次的空间,继续字符串的输入,当满的时候,再次申请,直到字符串输入完为止。
例如:
字符串长度为200(事先不知道此长度),第一次动态的申请10个长度的数组,当输入满之后,再次申请20个长度的内存,把第一次申请的内存中的内容复制到20个长度的里面,把10个的delete掉,当再满的时候再按上次方法处理···直到字符串输入完毕!

路过的朋友都看一下··
17 回复
#2
lz10919149992012-07-25 20:59
std::string不是都把这些做好了么?LZ想自己做一个?你的想法也是可以的。
#3
pangding2012-07-26 00:30
我也是建议楼主直接用 string 类。
#4
liudw22012-07-26 08:21
是啊,为什么不用string呢,多好用啊
#5
peach54602012-07-26 11:12
这不是stl的vector的基本思路吗?
#6
有容就大2012-07-26 11:45
呵呵 有想法。
#7
小糊涂神c302012-07-26 19:18
给自己顶贴,希望能有哪位大侠写一下关键代码!能给出合理建议的,定把分送上!
#8
pangding2012-07-26 20:17
如果要说关键代码,就是建议你去查醒 realloc() 的用法。至于合理建议,就是建议你用 string。你自己实现这个功能是有什么别的目的吗?
#9
zklhp2012-07-26 21:07
完全不懂来接分
#10
lonmaor2012-07-26 21:20
string::resize()可以完成这一切
详见:
http://technet.
#11
pangding2012-07-27 01:08
回复 10楼 lonmaor
我看楼主不是这意思。他是根本就不想用 string 这个类。
#12
小糊涂神c302012-07-27 08:07
以下是引用pangding在2012-7-27 01:08:19的发言:

我看楼主不是这意思。他是根本就不想用 string 这个类。
不想用现成的,还请各位据需发挥一下自己的能力,协助完成这样的想法!
#13
pangding2012-07-27 11:25
看你思路挺清楚的,就自己写呗,也不是太难。你是什么地方有困难?
#14
lz10919149992012-07-27 14:05
程序代码:
#include <iostream>
#include <cstring>
#include <cctype>
using namespace std;

class String {
public:
    String(const char* = 0);
    String(const String&);
    ~String();

public:
    int getLength();

    String& assign(const char*);
    String& assign(const String&);
   
    String& append(const char*);
    String& append(const String&);
   
    int compare(const char*);
    int compare(const String&);
   
    String& operator=(const char*);
    String& operator=(const String&);
   
    String& operator+=(const char*);
    String& operator+=(const String&);
   
    String operator+(const char*);
    String operator+(const String&);
   
    bool operator==(const char*);
    bool operator==(const String&);
   
    bool operator!=(const char*);
    bool operator!=(const String&);
   
    bool operator>(const char*);
    bool operator>(const String&);
   
    bool operator<(const char*);
    bool operator<(const String&);
   
    friend istream& operator>>(istream&, String&);
    friend ostream& operator<<(ostream&, const String&);
private:
    int capacity;
    char* storage;
};

String::String(const char* cstr)
{
    if (cstr) {
        capacity = strlen(cstr) + 1;
        storage = new char[capacity];
        strcpy(storage, cstr);
    } else {
        capacity = 1;
        storage = new char[capacity];
        *storage = '\0';
    }
}

String::String(const String& str)
{
    capacity = str.capacity;
    storage = new char[capacity];
    strcpy(storage, str.storage);
}

String::~String()
{
    if (storage)
        delete[] storage;
}

int String::getLength()
{
    return capacity - 1;
}

String& String::assign(const char* cstr)
{
    if (storage)
        delete[] storage;
    capacity = strlen(cstr) + 1;
    storage = new char[capacity];
    strcpy(storage, cstr);
    return *this;
}

String& String::assign(const String& str)
{
    if (storage)
        delete[] storage;
    capacity = str.capacity;
    storage = new char[capacity];
    strcpy(storage, str.storage);
    return *this;
}

String& String::append(const char* cstr)
{
    capacity += strlen(cstr);
    char* newStorage = new char[capacity];
    strcpy(newStorage, storage);
    strcat(newStorage, cstr);
    delete[] storage;
    storage = newStorage;
    return *this;
}

String& String::append(const String& str)
{
    capacity += str.capacity;
    char* newStorage = new char[capacity];
    strcpy(newStorage, storage);
    strcat(newStorage, str.storage);
    delete storage;
    storage = newStorage;
    return *this;
}

int String::compare(const char* cstr)
{
    return strcmp(storage, cstr);
}

int String::compare(const String& str)
{
    return strcmp(storage, str.storage);
}

String& String::operator=(const char* cstr)
{
    return assign(cstr);
}

String& String::operator=(const String& str)
{
    return assign(str);
}

String& String::operator+=(const char* cstr)
{
    return append(cstr);
}

String& String::operator+=(const String& str)
{
    return append(str);
}

String String::operator+(const char* cstr)
{
    String tmp(*this);
    tmp.append(cstr);
    return tmp;
}

String String::operator+(const String& str)
{
    String tmp(*this);
    tmp.append(str);
    return tmp;
}

bool String::operator==(const char* cstr)
{
    return compare(cstr) == 0;
}

bool String::operator==(const String& str)
{
    return compare(str) == 0;
}

bool String::operator!=(const char* cstr)
{
    return compare(cstr) != 0;
}

bool String::operator!=(const String& str)
{
    return compare(str) != 0;
}

bool String::operator>(const char* cstr)
{
    return compare(cstr) > 0;
}

bool String::operator>(const String& str)
{
    return compare(str) > 0;
}

bool String::operator<(const char* cstr)
{
    return compare(cstr) < 0;
}

bool String::operator<(const String& str)
{
    return compare(str) < 0;
}

void inflate(char** pBuffer, int* capacity, int incr)
{
    char* newBuffer = new char[*capacity + incr];
    strncpy(newBuffer, *pBuffer, *capacity);
    delete[] *pBuffer;
    *pBuffer = newBuffer;
    *capacity += incr;
}

istream& operator>>(istream& in, String& str)
{
    int capacity = 100;
    int increment = 100;
    char* buffer = new char[capacity], ch;
    int i = 0;
    while (in.get(ch) && !isspace(ch)) {
        if (i == capacity)
            inflate(&buffer, &capacity, increment);
        buffer[i++] = ch;
    }
    if (i == capacity)
        inflate(&buffer, &capacity, 1);
    buffer[i] = '\0';
    str.assign(buffer);
    return in;
}

ostream& operator<<(ostream& out, const String& str)
{
    return out << str.storage;
}

int main()
{
    String strs[] = {
        "As long as you love me",
        "Iridescent",
        "Love story",
        "I'm yours",
        "How to break a heart"
    };
    for (int i = 0; i < sizeof strs / sizeof *strs; ++i)
        cout << strs[i] << endl;
    String str;
    cin >> str;
    cout << str << endl;
    cin >> str;
    cout << str << endl;
    cout << (strs[0] == strs[0]) << endl;
    cout << (strs[0] == strs[1]) << endl;
    cout << (strs[0] < strs[1]) << endl;
    cout << (strs[1] < strs[0]) << endl;
    cout << (strs[0] > strs[1]) << endl;
    cout << (strs[1] > strs[0]) << endl;
    strs[0] += strs[1];
    cout << strs[0] << endl;
    strs[1] += " Hello";
    cout << strs[1] << endl;
    str = strs[0] + " " + strs[1];
    cout << str << endl;
}
#15
pangding2012-07-28 09:55
回复 14楼 lz1091914999
如果这是你以前就实现好的,我觉得发出来共享共享还好。如果是特意写的我觉得就挺亏的。楼主思路那么清楚,我又给了他提示,他就应该自己动动手。

而且你这个算法和楼主说的完全不同。你这个就是不断的 new delete 而已。而实际上,楼主那意思是,如果现在分配的内存存得下,就不应该 delete,直接用现在的就行了。扩容也应该使用倍容的技术。
其实在实现的时候也不费劲,除了 capacity 以外再多个 length 就行了。用 capacity 存开的内存长度,length 存字串长度就 OK。


[ 本帖最后由 pangding 于 2012-7-28 10:02 编辑 ]
#16
lz10919149992012-07-28 15:47
回复 15楼 pangding
恩,以前写的。
#17
粉红木耳2012-08-05 11:02
完全不理解  
#18
lyp8809242012-08-05 13:11
#include<iostream>
using namespace std;
class Vector{
   T*data;
   int sz;
   int max;
 public:
   Vector(int max_size=5):sz(0),data(0),max(max_size) {
        data=new T[max];
   }
 ~Vector(){delete[]data;}
  Vector(const Vector&v){
    sz=v.sz;
    max=v.max;
    data=new T[v.max];
    for(int i=0;i<sz;i++){
        data[i]=v.data[i];
    }
  }
 void expand(){
   max=max*2;
   T*t=new T[max];
   for(int i=0;i<sz;i++){
       t[i]=data[i];
   }
   delete []data;
   data=t;
 }
};
int main(){
 if(sz==max)
   expand();
 return 0;
}
我也是小白 写的不对的地方还请见谅 大体上可能符合你说的意思 同时往其他大牛多多指点
1