标题:函数调回指针的内存释放,(30分)请评价我编写的一个程序,
只看楼主
csj_65
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:63
专家分:163
注 册:2010-3-12
结帖率:100%
已结贴  问题点数:30 回复次数:7 
函数调回指针的内存释放,(30分)请评价我编写的一个程序,
比如说你申明一个函数
char *string_cmp(char *str, const char *str1)
在其中你为要返回的指针用malloc申请了一快内存地址,那你该如该将其释放呢?
上次的回答我不是很满意,请大家看看我写的一个程序吧。

函数调回指针的内存释放(25分)
程序代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX 256

static char *findchars;                //函数find_char的返回指针,返回被找到的字符,

char *find_char(char const *source, char const *chars);
//参数要搜索的字符串指针和给定字符集合
//带回找到的字符的集合的指针

int main (void)
{

    char *main_findchars;

    if ((main_findchars = (char *)malloc(sizeof(MAX))) == NULL)
    {
        printf("malloc error!\n");
        exit(1);
    }
    printf("we will find if there are members of the chars 'a,g9cd'");
    printf("in the string we input.\n");

    main_findchars = find_char("gfdgadgasd^dfe;(hdf8fgjgh,uy,i,oipujikthetwerqw", "a,g9cd");

    printf("the chars we find from the strings is %s\n", main_findchars);
    free(main_findchars);
    free(findchars);
    return 0;

}

char *find_char(char const *source, char const *chars)
{
    int count = 0;
    int i = 0;
    int j = 0;
    int charlen = strlen(chars);
    int sourcelen = strlen(source);
    int findc_yes_no[charlen];                        //数组每一位对应给定字符集中的相应的字符
                                                    //暂且称为开关数组,1和0代表有和没有
    if ((findchars = (char *)malloc(sizeof(chars))) == NULL)
    {
        printf("malloc error!\n");
        exit(1);
    }

    for(i = 0; i < charlen; i++)
    {
        findc_yes_no[i] = 0;
        *(findchars + i) = '\0';
    }

    for (i = 0; i < sourcelen; i++)
    {
        for(j = 0; j < charlen; j++)
        {
            if(*(source + i) == *(chars + j))
            {
                /*打印找到的字符在字符串中所处的位置*/
                printf("find char '%c' from the %dth of the strings\n", *(chars + j), i + 1);
                findc_yes_no[j] = 1;

            }
        }
    }

    for (i = 0; i < charlen; i++)                    //检查开关数组相应字符位
    {
        if (1 == findc_yes_no[i])                      //字符位若为1,把该字符放到findchars中去
        {
            *(findchars++) = *(chars + i);
            count++;
        }
    }

    return (findchars - count);

}
我是在函数中为返回指针开辟了动态存储空间,为了能在最后释放它,我把指针定义在函数外面,这样我就能在主函数中释放它,请问这种方法可行吗?有没有更好的方法,如果有请不吝赐教,非常感谢!
搜索更多相关主题的帖子: 内存 指针 函数 评价 
2010-04-29 18:57
xxwpk007
Rank: 4
等 级:业余侠客
帖 子:166
专家分:289
注 册:2007-7-29
得分:3 
main_findchars = (char *)malloc(sizeof(MAX)) // 指针指向你分配的地址

main_findchars = find_char("gfdgadgasd^dfe;(hdf8fgjgh,uy,i,oipujikthetwerqw", "a,g9cd"); // 指针指向你找到后返回的地址

你只是改变了指针的指向而已。

main_findchars = (char *)malloc(sizeof(MAX))// 这样写没意义啊
2010-04-29 19:17
kingsroot
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:1
帖 子:284
专家分:1159
注 册:2010-3-28
得分:3 
通俗点说,就是栈里面的内存空间分别属于不同的函数所有,但是堆里面的内存属于共用的,不是属于某个函数,你在某个函数里面申请了内存,只能表示堆中的某块内存被使用了,但是不表示这块内存属于某个函数,所以在堆中申请的内存可以在任何地方释放~~~~
2010-04-29 21:01
succubus
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:4
帖 子:635
专家分:1080
注 册:2007-10-7
得分:3 
代码错误很多
不过和你问的问题无关就不说了。。。
看你的问题是在函数里动态申请了一块内存
但是返回值却不是指向这块内存的指针
所以你头疼释放问题。。。
解决方法之一就是给find_char函数加一个char**类型的形参
e.g
程序代码:
char *find_char(char const *source, char const *chars, char** buffer)
{
    ...
    *buffer = (char *)malloc(sizeof(chars));
    ...
}

int main()
{
    char* temp;
    chat* main_findchars;
    ...
    main_findchars = find_char("gfdgadgasd^dfe;(hdf8fgjgh,uy,i,oipujikthetwerqw", "a,g9cd", &temp);
    ...
    if (NULL != temp)
    {
        free(temp);
        temp = NULL;
    }
    ...
}



[ 本帖最后由 succubus 于 2010-4-30 08:54 编辑 ]

[url=http:///view/aDU1]/image/aDU1.gif" border="0" />[/url]
2010-04-30 08:51
lixiangyang
Rank: 2
等 级:论坛游民
帖 子:16
专家分:21
注 册:2010-4-10
得分:3 
不懂啊,悲哀
2010-05-01 08:42
南国利剑
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:29
帖 子:1165
专家分:3536
注 册:2010-4-12
得分:3 
回复 楼主 csj_65
回答楼主最后的问题:
你可以在在一个被调函数中开辟一个内存,而不在被调函数里释放它。
但是你得把这片内存的首地址返回给主函数或者主调函数,并用一个指针接受,
然后在主调函数或者主函数结束前释放这个指针就可以了。

南国利剑
2010-05-03 18:21
南国利剑
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:29
帖 子:1165
专家分:3536
注 册:2010-4-12
得分:0 
回复 3楼 kingsroot
我不是很同意二楼的说法。
我个人认为:堆区和栈区的数据的不同之处在于二者的生存期不同。
堆区的生存期一般是整个程序的运行时间或者说是它没有被释放之前。
而栈区的数据的生存期,一般是一个函数的运行时间。

南国利剑
2010-05-03 18:27
wsj3000
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:78
专家分:161
注 册:2009-8-4
得分:3 
汗~~~
c语言的内存分配类型问题。
一共4类:
1,text类型,就是code,只读,加载二进制文件的时候直接拷贝到只读区域。
2,static类型,生命周期整个程序运行期间,在二进制文件加载的时候直接拷贝到内存,可读写,公共变量和static 关键字申请的变量属于这种类型。
3,栈类型,也就是最普通的int ,long,等申请的空间,在栈上分配,生命周期在函数内,就是说如果是函数中申请的,推出这个函数时会清除掉。注意他不是直接拷贝到堆栈上的,而是系统push()到堆栈上的,所以,在函数内你可以这么写:int n = 10; int arr[n];但是在所有函数之外就不可以,因为公共变量存在静态区域,需要加载是直接拷贝到内存,而这个时候编译认为n是未知的。但是用push()加载的话,loader可以先取n的值,从而之际到需要push()多少个空间。
4,堆类型,就是malloc()申请的,其实malloc函数封装了一个系统调用,这个调用分配一部分由内核管理的内存空间,由内核记录这段空间的开始终止地址,并返回开始地址;而且这段内存的唯一标记就是开始地址,所以任何函数内只要free(p);就是调用一个系统调用释放p开始的地址空间,所以p = malloc(),可以在任何一个函数内使用,而在其他函数内free(p)就可以释放这段内存。没错,如果你随便free(x)一个地址,而如果x恰好是某块内存开始地址的话,那么这块内存会被释放。

[ 本帖最后由 wsj3000 于 2010-5-3 20:32 编辑 ]
2010-05-03 20:00



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-304886-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.030981 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved