下面两种做法,哪个比较合理,即指针p频繁赋值的时候,不影响执行速度和内存占用(包括尽可能少的碎片)。
1、
int i;
char * p;
for (i=0;i<65535;i++)
{
  p="abcdefg";
  p="abcd";
  p="ab";
  p="abcdefghijk";
}2
int i;
char * p;
p=new char[65535];
for (i=0;i<65535;i++)
{
  p="abcdefg";
  p="abcd";
  p="ab";
  p="abcdefghijk";
}
delete p;

解决方案 »

  1.   

    to caomuyong1(叶开) 
    new char[65535]看起来是申请了一大块内存,但我想讨论的是多次赋值的影响
    简单说就是
      p="abcdefg";
      p="abcd";
      p="ab";
    如果是new了一块空间,那是否无论p如何变化,都保持该空间?
    如果第一种方式,那么上面三条执行过后,p占的内存是两个字节(ab),还是14个字节(abcdefg),有没有碎片的产生?
      

  2.   

    to beyondtkl(大龙驹<弱水三K, 我取1bit>) 
    第一种和第二种都没事么?
      

  3.   

    to GoldenSword(金错刀) 
    为什么
    第二种是否只在申请的内存范围内操作
    第一种内存是怎么申请的?
      

  4.   

    to beyondtkl(大龙驹<弱水三K, 我取1bit>) 
    能否详细解释一下,谢谢!
    比如p="aa";
    有人说当p="abc"是改变了指针的指向,就是抛弃了原来的地址,指向新地址,而p[0]='a';p[1]='b';p[2]='c';p[3]='\0';才是为指针指向的内容赋值,所以两种方法都有问题
      

  5.   

    可能上面的代码是什么意思呢?:
    int i;
    char * p;              //定义指针
    p=new char[65535];    //内存动态分配地址给P  ,对后面有什么用??
    for (i=0;i<65535;i++)
    {
      p="abcdefg";     //P指向字符串"abcdefg"首地址 指针变量不在指向p=new char[65535]的地址了
      p="abcd";       //那么new char[65535]成了真正的碎片了.
      p="ab";
      p="abcdefghijk";
    }
    delete p;
      

  6.   

    to linzi123(林子) 
    测试指针p频繁赋值的时候,不影响执行速度和内存占用(包括尽可能少的碎片)。
    我也认为会消耗光内存资源,但实际是下面程序没事,所以不理解
    理论上应该消耗光至少65535*65535*36/1024/1024=146451MB(第一个串)内存资源for (i=0;i<65535;i++)
    {
     for (j=0;j<65535;j++)
      {
       p="abcdefghijklmnopqrstuvwxyz1234567890"; 
       p="abcd";       
       p="ab"; 
       p="abcdefghijk";//是不是可认为上面三个都成了碎片?
     }
    }
    delete p;
      

  7.   

    ???我晕了,我觉得第一种和第二种没什么区别(就分配的速度而言),因为只是修改了p的值而已
    p="abc"是改变了指针的指向,就是抛弃了原来的地址,指向新地址,我同意这种说法
      

  8.   

    to mxp:
    在你的最后一个帖子中,"abcdefghijklmnopqrstuvwxyz1234567890"占用的是堆栈空间,当第二个for循环一遍后,"abcdefghijklmnopqrstuvwxyz1234567890"会被释放,然后重新分配
      

  9.   

    to barsteng(barsteng) 
    您的意思是释放内存?
    我最开始认为重新赋值就是释放以前内存,指向新地址,不会产生碎片,但不敢确认,也不敢说new了空间后赋值就不是在该空间操作了尤其大家的答案各不相同,所以也有些认不准了
    主要疑问
    1、new空间后,执行赋值操作,是否还在new的空间内?
    2、多次赋值会不会产生内存碎片?
    3、在赋值的时候new空间和直接操作有无区别,是否只要是赋值就不应该new空间?(如果不赋值,不new一个空间p[0]=字符方式是无法执行的)
      

  10.   

    1、不在new的空间内
    2、多次赋值(象你程序中的),不会产生碎片
    3、你是在给指针赋值,相当于将指针指向了其他的空间,
    for (i=0;i<65535;i++)
    {
    p="abcdefg";
    p="abcd";
    p="ab";
    p="abcdefghijk";
    }
    之后,p指向的是一个非法空间,无论怎样,这样写程序都是危险的
      

  11.   

    :(危险的意思是如果你不小心delete了p,那么会出错,而且你这么写程序,让其他程序员看的比较别扭
    int i;
    char * p;
    p=new char[65535];
    for (i=0;i<65535;i++)
    {
    p="abcdefg";
    p="abcd";
    p="ab";
    p="abcdefghijk";
    }
    delete p;
    这种情况下会崩溃
      

  12.   

    就频繁赋值这个问题两种做法没有任何区别,但第二中做法肯定出错,赋值后p指向的内存早不是new出来的那块了,在delete的话肯定是崩溃。
      

  13.   


    你没有在debug下执行?我执行的时候ASSERT了一个错误啊
      

  14.   

    to:mxp(mxp) ( ) for (i=0;i<65535;i++)
    {
     for (j=0;j<65535;j++)
      {
       p="abcdefghijklmnopqrstuvwxyz1234567890"; 
       p="abcd";       
       p="ab"; 
       p="abcdefghijk";//是不是可认为上面三个都成了碎片?
     }
    }
    delete p;"abcdefghijklmnopqrstuvwxyz1234567890"; 
    "abcd";       
    "ab"; 
    "abcdefghijk";
    这些都是作为常量字符串分配在静态空间里面的,怎么会是内存碎片片呢?
      

  15.   

    第二个明显错了,p被改变了,然后再delete p,肯定crash
      

  16.   

    就频繁赋值这个问题两种做法没有任何区别,但第二中做法肯定出错,赋值后p指向的内存早不是new出来的那块了,在delete的话肯定是崩溃。有道理,但我弄了个函数调用1000次,delete,也没崩溃和报错。根据规则,new出的空间如果不删除就会内存泄漏,第二种做法是否应该有碎片?
      

  17.   

    好,我把函数贴出来,大家看一下
    /*
    类说明:指针测试
    */
    class PointerTest
      {
       private:
         char *p;
         void DeleteTest();//指针删除函数
       public:
         void RunTest(); //外部调用函数
      };
    /*
    函数说明:测试删除指针
    返回值:无
    参数:无
    */
    void  PointerTest::DeleteTest()
    {
      int i;
      for (i=0;i<65535;i++)
      {
         p="abcdefghijklmnopqrstuvwxyz1234567890";
         p="abcd";
         p="ab";
         p="abcdefghijk";
      }
      delete p; //我删了
    }
    /*
    函数说明:调用删除指针函数1000次
    返回值:无
    参数:无
    */
    void  PointerTest::RunTest()
    {
      int i;
      for(i=0;i<1000;i++)
       DeleteTest();
    }外部调用如下:
    PointerTest Ptest;
    Ptest.RunTest();

    PointerTest *Ptest;
    Ptest=new PointerTest();
    Ptest->RunTest();
    都没出错或崩溃!!
      

  18.   

    1、
    int i;
    char * p;                        //栈
    for (i=0;i<65535;i++)
    {
      p="abcdefg";                   //栈,每次循环自动释放
      p="abcd";                      //栈,每次循环自动释放
      p="ab";                        //栈,每次循环自动释放
      p="abcdefghijk";               //栈,每次循环自动释放
    }2
    int i;
    char * p;                        //栈
    p=new char[65535];               //堆,一块完全没有用到的内存......
    for (i=0;i<65535;i++)
    {
      p="abcdefg";                   //栈,每次循环自动释放,此时失去对new char[65535]的地址,将无法释放
      p="abcd";                      //栈,每次循环自动释放
      p="ab";                        //栈,每次循环自动释放
      p="abcdefghijk";               //栈,每次循环自动释放
    }
    delete p;                        //没有起到释放内存的目的,只是将p的内容失效,堆里面的那块内存铁定要泄露了。
      

  19.   

    凡是new出来的内存都放在堆里,而指向这块内存的指针则放在栈里。
    同时栈里还放有局部变量,一旦超出生存周期就会被自动删除。堆是很大的,32位操作系统可以有4G的大小,栈比较小,若果栈溢出,程序很定会出错的,我曾经在研究黑白棋的算法的时候,一个递归调用里,全部用的都是数组,结果把栈给挤满了......栈比堆要快。栈不存在碎片问题,这是由它的数据结构决定的。
    堆内频繁使用new/delete会造成大量内存碎片,堆的性能也会下降。
      

  20.   

    同意 konista(M) ( ) 信誉:100 
    第二种,是吃饱了没事干,分配了堆的空间,delete会泄漏,不一定会崩溃,看你的内存顶不顶得住
      

  21.   

    同意楼上。
    只有频繁 分配 然后释放才会产生碎片比如 你先分配10K 然后分配20K然后释放10K。。然后分配10BYTE..
    这样系统在后面的分配过程中 如果没有足够用的内存用 就会把那些 零散的内存进行整合 就是合成一块以供后面的使用 这样的效率是非常低的。。所以应该避免这种情况。。你如果分配了一段内存了 表示告诉系统,这块系统我在用,系统就不会跟你抢的,所以你对这段内存多么频繁的写,读,操作都没事。。因为这是不同的概念。。
      

  22.   

    ps:
    delete p;//只把栈里的p内容置为失效,堆里的空间没有释放
    应该改成
    delete [] p;//释放堆里的空间
      

  23.   

    to konista(M) 
    for (i=0;i<65535;i++)
    {
      p="abcdefg";                   //栈,每次循环自动释放
      p="abcd";                      //栈,每次循环自动释放
      p="ab";                        //栈,每次循环自动释放
      p="abcdefghijk";               //栈,每次循环自动释放
    }
    为什么是每次循环自动释放,而不是在p指向下一个串的时候就释放?
    如果是指向栈,当delete p的时候意味着p失效,是否意味着栈内存释放了
      

  24.   

    p="abcdefg;  //語法根本就有問題;速度就要取決於你的重載函數還是用strcpy函數是怎麼寫的!
      

  25.   

    to konista(M) 
    delete [] p;//释放堆里的空间
    p的地址都变了,这个会释放堆里的空间?
    to zhoujiamurong(有分俺就不要,俺要知识) 
    如果按上面的说法,仅是丢失了16K的内存,怎么会崩溃?
      

  26.   

    to ShiGang(Sucess) 
    不会吧,这么多人都执行了,现在思维混乱中...to beyondtkl(大龙驹<弱水三K, 我取1bit>)
    频繁new和delete会降低系统性能这个知道,但现在普遍认为栈比较快
    采用第一种方式的时候,应该是自动占用和释放栈中的内存,应该避免?
      

  27.   

    p在delete 之前是指向栈的
    ***************************************************
    p="abcdefghijk";               //栈,每次循环自动释放
    ***************************************************
    所以,你在释放栈的空间,栈是系统自己释放的,所以系统还会释放,就有问题了
      

  28.   

    to  zhoujiamurong(有分俺就不要,俺要知识) 
    但我怎么没测试出崩溃?
    另外,为什么是每次循环自动释放,而不是指向下一个地址自动释放?
      

  29.   

    我用的是VC6.0加windows2000,VC中有断言判断内存块的类型   
          /* verify block type */
            _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
      

  30.   

    我突然发现一个问题,
    ***************************************************
    p="abcdefghijk";               //栈,每次循环自动释放
    ***************************************************
    p根本不是指向栈的,而是数据区
      

  31.   

    /*
    我突然发现一个问题,
    ***************************************************
    p="abcdefghijk"; //栈,每次循环自动释放
    ***************************************************
    p根本不是指向栈的,而是数据区
    */
    是啊,因为p本身就是一个指针啊
      

  32.   

    p根本不是指向栈的,而是数据区但前面很多人都说是指向栈的,听谁的比较可靠本来
    class a{}
    a b1
    a *b2;
    b1是栈中的,b2是堆里的,但现在直接赋值指针是指向哪里的?问题结论发展:
    1、第一种好,因为第二种new的空间大,即认为第二种在new空间内操作
    2、第二种好,因为第二种有内存池,不会产生碎片
    3、第二种好,因为第一种是栈分配空间,第二种是堆分配空间
    4、第一种和第二种都有问题,因为分配空间无效,直接改变指针地址,会消耗光内存
    5、第一种和第二种一样,最后都是在栈分配空间,不会消耗内存,循环时自动回收(为什么循环时回收?),第二种new无作用,有碎片
    6、第二种的delete会出错,因为p地址变了
    7、第二种的delete不会出错,除非是不停地new空间,消耗光资源
    8、第二种的delete会出错,因为不能释放两次
    9、栈比堆快,不要用频繁new delete,意思是用第一种好点?如果非要用最好new了就独享
    10、指针直接赋值不能这么写?
    11、直接赋值不是栈分配空间,是指向数据区的
      

  33.   

    p="abcdefghijk"; //栈,每次循环自动释放
    p根本不是指向栈的,而是数据区
    因为p本身就是一个指针啊
    应换种问法
      

  34.   

    请问林子,C里面也有栈内和堆内这种说法吗,我只是在JAVA里面看到这个概念
      

  35.   

    如果有一个指针
    其内容需要不停地变成从端口传过来的字符串(需要解密运算,最终返回结果是一个String)
    性能最好和并且安全的方法是什么?是让指针指向这个串吗?
      

  36.   

    http://community.csdn.net/Expert/FAQ/FAQ_Index.asp?id=203045