我想了解从函数调用返回指针的行为。假设我有以下简单代码:
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之前?
答案 0 :(得分:5)
在
free(buff);
取消引用buff
的任何其他操作都是 未定义的行为 。
您的函数test()
分配一个缓冲区,然后free
之前将其作为main
返回ssd
。
因此,当ssd
中的main
被取消引用时,虽然指针仍然具有malloc
分配的相同值,但它不再指向您“拥有”的内存。从那时起,任何事情都可能发生。您的代码可能仍然有效,或者可能没有。
答案 1 :(得分:0)
最初由buff
指向的内存不会被覆盖,从而保留您存储在其中的值。
这通常就是我们所说的“包含垃圾的内存”,但是自从你初始化它之后一切正常。
答案 2 :(得分:0)
来自libc文档,
有时,free实际上可以将内存返回给操作系统 并使过程更小。通常,它所能做的只是稍后允许 调用malloc来重用空间。与此同时,空间仍然存在 在您的程序中作为malloc内部使用的自由列表的一部分。
免费通话并不能保证空间被清理干净。但保证(至少通过GNU libc实现)是
为了证明这一点,我修改了你的程序,如下所示。它基本上在你的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>