0
Consider the following functions
void alloco(int **ppa)
{
    int i;
    printf("inside alloco %d\n",ppa); /*this function allocates and fills 20 * sizeof(int) bytes */
    *ppa = (int *)malloc(20 * sizeof(int));
    /*fill all 20 * sizeof(int) bytes */
}

int main()
{
    int *app = NULL;
    int i;
    printf("inside main\n");
    alloco(&app);
    for(i=0;i<20;i++) /*ISSUE::how will i know to traverse only 20 indexes?*/
    printf("app[%d] = %d \n", i, app[i]);
    return(0);
}

基本上 main() 将如何知道要遍历的字节数,即 alloco() 函数分配的内存。字符数组中是否有像 NULL 这样的分隔符?

4

3 回答 3

2

这是不可能的,您需要将该值保留在某个地方,例如您可以这样做,

void alloco(int **ppa, int count)
{
    int i;

    printf("inside alloco %d\n",ppa);
    *ppa = malloc(count * sizeof(int));
    if (*ppa == NULL)
        return;
    for (i = 0 ; i < count ; ++i)
        /* fill it here. */
}

int main()
{
    int *app;
    int  i;
    int  count;

    count = 20;
    app = NULL;
    printf("Inside main\n");
    alloco(&app, count);
    if (app == NULL)
        return -1;    
    for (i = 0 ; i < count ; i++)
        printf("app[%d] = %d \n", i, app[i]);
    /* done with `app' */
    free(app);
    return 0;
}

许多其他组合也可以工作,例如

int alloco(int **ppa)
{
    int i;

    printf("inside alloco %d\n",ppa);
    *ppa = malloc(20 * sizeof(int));
    if (*ppa == NULL)
        return;
    for (i = 0 ; i < count ; ++i)
        /* fill it here. */
    return 20;
}

int main()
{
    int *app;
    int  i;
    int  count;

    printf("Inside main\n");

    app = NULL;
    count = alloco(&app);
    if (app == NULL)
        return -1;    
    for (i = 0 ; i < count ; i++)
        printf("app[%d] = %d \n", i, app[i]);
    /* done with `app' */
    free(app);
    return 0;
}

但我个人不喜欢这样,因为如果要使用固定数量的整数,那么malloc()只使用它不是一个好主意,

int main()
{
    int  app[20];
    int  i;

    printf("Inside main\n");    
    for (i = 0 ; i < sizeof(app) / sizeof(app[0]) ; i++)
        printf("app[%d] = %d \n", i, app[i]);
    return 0;
}
于 2015-04-30T15:07:45.650 回答
1

字符数组中是否有像 NUL L这样的分隔符?

如果你定义一个,是的。

但是,这只有在您的用例不需要所有可能的整数值时才有可能。

例如,如果您只需要正值,包括0您可以将值定义为-1“数组结束”标记。

然后,您将再为数组分配一个元素,然后再分配-1给这个额外的最后一个数组元素。

例子:

#include <stdlib.h> /* for malloc */
#include <errno.h> /* for errno */

#define EOA (-1)

int array_allocate(int ** ppi)
{
  int result = 0;

  if (NULL = ppi)
  {
    result = -1;
    errno = EINVAL;
  }
  else
  {
    size_t number_of_elements = ...; /* Assign some positive value here. */

    *ppi = malloc((number_of_elements + 1) * sizeof ** ppi);
    if (NULL == *ppi)
    {
      result = -1;
    }
    else
    {
      (*ppi)[number_of_elements] = EOA;
    }
  }

  return result;
}

ssize_t array_number_of_elements(int * pi)
{
  int result = 0;

  if (NULL == pi)
  {
    result = -1;
    errno = EINVAL;
  }
  else
  {
    int * pi_tmp = pi;
    while (EOA != *pi_tmp)
    {
      ++pi_tmp;
    }

    result = pi_tmp - pi;
  }

  return result;
}

像这样使用它:

#include <stdlib.h> /* for size_t and ssize_t */
#include <stdio.h> /* for printf and perror */

int array_allocate(int **);
ssize_t array_number_of_elements(int *);

int main(void)
{
  int result = EXIT_SUCCESS;
  int * pi = NULL;

  if (-1 == array_allocate(&pi))
  {
    result = EXIT_FAILURE;
    perror("array_allocate() failed");
  }
  else
  {
    ssize_t result_number_of_elements = array_number_of_elements(pi);
    if (-1 == result_number_of_elements)
    {
      result = EXIT_FAILURE;
      perror("array_number_of_elements() failed");
    }
    else
    {
      size_t number_of_elements = result_number_of_elements;
      printf("The number of array's elements is %zu.\n", 
        number_of_elements);
    }
  }

  free(pi); /* Clean up. */

  return result;
}
于 2015-04-30T15:40:56.717 回答
0

成为一名三星级程序员

您可以轻松地在函数中分配一些固定数量的元素(小于最大值),而无需在调用者函数和被调用者之间传递元素数量。但是,它需要创建一个指针数组,指向类型如何/为什么?本质上,您将数组视为以空字符结尾的字符串,最初将所有指针分配给数组中的类型,NULL并仅根据需要为它们分配空间。(分配calloc使这很容易)当数组在调用者中重新使用时,它允许迭代所有填充值,直到到达第一个空指针。

现在授予,

简单地将指向大小的指针作为附加参数传递给您的函数更有意义 [1]

并且消除了对三星级评级的需要,但出于示例的目的,请享受一段时间成为三星级程序员

#include <stdio.h>
#include <stdlib.h>

#define INITSZ 21

void alloco (int ***ppa)
{
    printf("inside %s\n", __func__);

    int i = 0;

    /* allocate 21 pointers-to-int */
    if (!(*ppa = calloc (INITSZ, sizeof **ppa))) {
        fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__);
        exit (EXIT_FAILURE);
    }

    /* allocate/fill 20 values (or anything less than 21) */
    for (i = 0; i < INITSZ - 1; i++) {
        if (!((*ppa)[i] = calloc (1, sizeof ***ppa))) {
            fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__);
            exit (EXIT_FAILURE);
        }
        *((*ppa)[i]) = i * 2;
    }
}

int main()
{
    int **app = NULL;
    int i = 0;

    printf ("inside main\n");
    alloco (&app);

    /*ISSUE::how will i know to traverse only 20 indexes?*/

    while (app[i]) {
        printf("app[%d] = %d \n", i, *(app[i]));
        i++;
    }

    return(0);
}

使用/输出

$ ./bin/alloc_array+1
inside main
inside alloco
app[0] = 0
app[1] = 2
app[2] = 4
app[3] = 6
app[4] = 8
app[5] = 10
app[6] = 12
app[7] = 14
app[8] = 16
app[9] = 18
app[10] = 20
app[11] = 22
app[12] = 24
app[13] = 26
app[14] = 28
app[15] = 30
app[16] = 32
app[17] = 34
app[18] = 36
app[19] = 38

脚注 [1]:为了清楚起见,在引文中添加了重点,即该解决方案旨在展示什么是可能的,而不是最有效或最实用的。

于 2015-04-30T16:14:27.713 回答