在return语句之前理解free()缓冲区

时间:2016-09-25 19:17:52

标签: c pointers memory-management

我想了解从函数调用返回指针的行为。假设我有以下简单代码:

int main(){
    int i;
    float *ssd;
    ssd = test();

    for (i = 0; i < 3; ++i) {
        printf("%f, ", ssd[i]);
    }
    printf("\n \n");

    memset(ssd, 0.0, 3*sizeof(float));

    for (i = 0; i < 3; ++i) {
        printf("%f, ", ssd[i]);
    }
    printf("\n \n");

}

float *test(){

    float *buff = malloc(3* sizeof(float));
    int i;
    for (i = 0; i < 3; ++i) {
        buff[i] = (float) (6.31 + i);
    }

    free(buff);
    return buff;

}

如您所见,我在buff内创建了一个临时缓冲区test()。在我回来之前,我在buff陈述之前释放了return。虽然我测试了它并且结果符合预期,但我不明白test()函数如何返回buff值,即使free(buff)return buff之前?

3 个答案:

答案 0 :(得分:5)

free(buff);

取消引用buff的任何其他操作都是 未定义的行为

您的函数test()分配一个缓冲区,然后free之前将其作为main返回ssd

因此,当ssd中的main被取消引用时,虽然指针仍然具有malloc分配的相同值,但它不再指向您“拥有”的内存。从那时起,任何事情都可能发生。您的代码可能仍然有效,或者可能没有。

答案 1 :(得分:0)

最初由buff指向的内存不会被覆盖,从而保留您存储在其中的值。

这通常就是我们所说的“包含垃圾的内存”,但是自从你初始化它之后一切正常。

答案 2 :(得分:0)

来自libc文档,

  

有时,free实际上可以将内存返回给操作系统   并使过程更小。通常,它所能做的只是稍后允许   调用malloc来重用空间。与此同时,空间仍然存在   在您的程序中作为malloc内部使用的自由列表的一部分。

免费通话并不能保证空间被清理干净。但保证(至少通过GNU libc实现)是

  1. 在将来调用任何动态内存分配例程时,运行时可能会使用这样释放的空间。
  2. 为了证明这一点,我修改了你的程序,如下所示。它基本上在你的test()函数中添加了一个for循环,它只分配和释放buff的n次(e.x.10次)并打印缓冲区的内容。因此,每次运行程序时,它都会首次打印内容,并且当调用malloc()和free()时,* buff的内容将被清除并打印垃圾。 (在mac上测试,gcc 4.8+)。 希望这可以帮助。

    public class HeightConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            double d1 = (double)values[0], d2 = (double)values[1];
            return (d1 == d2 ? "equal" : "not equal");
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    
        <Window x:Class="WpfApplication4.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfApplication4"
            xmlns:sys="clr-namespace:System;assembly=mscorlib"
            Width="300" Height="200">
    
        <Window.Resources>
            <local:HeightConverter x:Key="HeightConverter" />
        </Window.Resources>
    
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto" />
                <RowDefinition />
            </Grid.RowDefinitions>
    
            <TextBlock>
                <TextBlock.Text>
                    <MultiBinding Converter="{StaticResource HeightConverter}">
                        <Binding ElementName="Scroll" Path="VerticalOffset" />
                        <Binding ElementName="Scroll" Path="ScrollableHeight" />
                    </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
    
            <ScrollViewer x:Name="Scroll" Height="200" VerticalScrollBarVisibility="Auto" CanContentScroll="True" Grid.Row="1">
                <ListBox>
                    <!-- long list of items -->
                </ListBox>
            </ScrollViewer>
        </Grid>
    
    </Window>