函数知道它的参数占用多少内存? [英] does a function know how much memory its parameters occupy?

查看:199
本文介绍了函数知道它的参数占用多少内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我们调用函数传递值时,我们在内存中复制实际参数的值。



问题是:函数是否知道如何它的参数在内存中占用多少空间?如果答案是肯定的,我们如何在功能范围内检索它?



如果答案为否,我们是否有潜在的隐藏内存错误?



考虑这个例子:

When we call function passing by value, we are making a copy in memory of the actual parameters' value.

The question is: does the function know how much space its parameters occupy in memory? If the answers is yes, how we can retrieve it in function scope?

If the answers in no, do we have a potentially hidden memory error?

consider this example:

#include <stdio.h>
void func(char * X)
{
    X +=98;
    *X='C'; //is this really OK? or we have hidden memory error?
    *++X='\0';
     --X;
    puts(X);     }

int main()
{
    char A[100];
    char *B =A;
    func(B);
    return 0;
}

推荐答案

这没关系但风格很糟糕,因为你的func在一些内存中戳而不知道是不是它没关系。



这取决于输入指针:大小必须足够大,你必须拥有写权限。否则它会崩溃。



例如更好:



This is OK but it is bad style, because your func is poking in some memory without knowing whether it is OK.

It depends on the input pointer: the size must be great enough and you must have write rights. Else it crashes.

Better is for instance:

void func(char * buffer, int count)
{
if( count > 100) 
{
 //manipulate all valid bytes 
}
}


我的问题不是很清楚,但我认为你的困惑与数组有关。

在C中的名字是array是它的地址(指向其第一个元素的指针)。因此,如果您将数组传递给实际的函数,那么您将传递第一个元素的地址而不传递其他信息。没有创建数据的内存副本。所以你没有副本而你不知道数组的尺寸。如果你在数组名称上使用'sizeof'operatoor,你将获得一个指针的大小(不是数组的大小)。

如果是数组,你问题的答案是:< b>不,函数不知道参数的大小是什么。

其他类型数据的情况处理方式不同,但函数仍然不知道参数的维度。

考虑一个结构。对于通过引用或按值传递数据的结构会产生差异。

在这种情况下,编译器无法在调用堆栈帧上分配结构(因为这会首先产生堆栈帧处理问题,然后是内存然后,编译器通过公共约定,分配一个结构的私有副本(通常在堆栈内存上使用alloca()),然后将指向该结构的指针传递给被调用的函数。编译器透明地处理整个事情,就像传递了真实数据值而不是指向副本的指针一样,无论如何,访问私有副本的用户相当于按值传递。

为了完整起见,编译之前的编译器检查结构维度,如果它适合基本类型维度,则直接传递结构。即

Your question is not very clear to me, but I assume that you perplexity is related to arrays.
In C the name of an array is it's address (a pointer to its first element). So if you pass an array to a function in reality you're passing the address of the very first element and no other information. No memory copy of the data is created. So you don't have a copy and you don't know the dimensions of the array. And if you use the 'sizeof' operatoor on the array name you'll get the size of a pointer (not the size of array).
The answer to your question in case of arrays is: No, the function doesn't know what is the size of the parameter.
The case of other types of data is handled differently, but the function still doesn't know the dimension of the parameter.
Consider a structure. For structures passing data by reference or by value makes the difference.
In this case the compiler cannot allocate the structure on the calling stack frame (because this would create problems firstly with stack frames handling, then with memory access boundary), the compilers then, by common conventions, allocates a private copy of the structure someway (normally on stack memory using alloca()), then passing a pointer to that structure to the called function. The compiler handles the whole thing transparently as if the real data value was passed instead of a pointer to the copy, and anyway for the user accessing a private copy is equivalent to a passage by value.
For the sake of completeness, the compiler before to act checks the structure dimension and if it can fit in a basic type dimension pass the structure directly. I.e.
struct _tagMyStr
{
  short a;
  short b;
};



这个由2个短路组成的结构可以放在一个整数中,而不是直接在堆栈上传递(或者在64位__fastcall中注册)。


This struct made of 2 shorts can fit in one integer than it is passed directly on the stack (or register in 64bits __fastcall).


如果你的意思是问:一个函数知道,它的一个参数指向的内存有多大,答案是明确的否。通过参数传递的指针就像任何指针一样,程序无法分辨,是否
指向单个元素或许多此类元素,也不是多少。



所以你的例子严格来说是非法的C.用

If you mean to ask: Does a function know, how large the memory is that one of its parameters points to, the answer is a clear "no". A pointer that is passed via a parameter is just like any pointer and the program has no way of telling, whether it
points to a single element or many such elements, nor how many.

And so your example is strictly speaking illegal C. With
X +=98;
*X='C'; //is this really OK? or we have hidden memory error?
*++X='\0';
 --X;



您正在访问无法控制的内存。在给定的示例中,主程序提供长度为100的数组,一切顺利。但是其他人可以使用较小的阵列调用你的函数然后你的程序可能会崩溃。



至少你要做的是评论你的函数的接口一种表明X必须指向至少100个字符的数组的方法。



更好的是引入第二个参数来指定<的长度br />
由X传递的数组,如解决方案1中所示。


you are accessing memory that you have no control over. In the given example, in which the main program provides an array of length 100, all goes well. But someone else could call your function with a smaller array and then your program might crash.

The very least you had to do is to comment the interface of your function in a way that makes it clear that X must point to an array of at least 100 chars.

Better would be to introduce a second parameter that specifies the length of the
array passed by X, as was suggested in solution 1.


这篇关于函数知道它的参数占用多少内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆