返回从功能二维数组 [英] return 2d array from function

查看:123
本文介绍了返回从功能二维数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个加载数据的功能,并把它们放到一个数组

I have an function that loads data and put them into an array

char array_of_string() {
    char **array;
    size_t size = 5;
    size_t index = 0;
    size_t length = 0;
    int rd;
    char *line;
    array = (char **) malloc(size * sizeof(char*));
    while ((rd = getline(&line, &length, 0) != -1) {
      array[index] = malloc(strlen(line) + 1 * sizeof(char));
      strncpy(array[index], line);
      index++    
    }

   free(line);
   return array;
}

int main() { 
  char **here;
  here = array_of_strings();
}

但是,这并不工作,这是尝试,我怎样才能使它发挥作用的结果EBST?

but this does not work , this is the ebst result of trying , how can i make it work?

推荐答案

由于在评论中提到,你有几个问题需要纠正。与开始为什么函数getline 不工作? 函数getline 需要 FILE * 流指针不是的文件描述符的作为其第三个参数。使用标准输入而不是 0 将解决这个问题。剩下的问题涉及分配。那些已经评价了讨论和校正实例如下所示。

As mentioned in the comment, you have several issues to correct. Starting with "Why is getline not working?" getline takes a FILE * stream pointer not a file descriptor as its third parameter. Using stdin instead of 0 will correct the problem. The remaining problems deal with allocation. Those have been discussed in the comments and corrected examples are shown below.

你会遇到的最大问题是我怎么会知道有多少行实际上是读?你有硬codeD'5',但如果你读比 5

The biggest issue you will run into, is "How will I know how many lines were actually read?" You have hard-coded '5', but what if you read less than 5?

要回答这个问题,你需要,至少,传递一个指针作为参数传递给你的 array_of_string 函数,并更新与首页值,使行数读可回调用函数(的main()在这种情况下)。这样一来,你总是知道的行数读出。例如:

To answer the question, you need to, at minimum, pass a pointer as a parameter to your array_of_string function, and update it value with the index value so that the number of lines read is available back in the calling function (main() in this case). That way, you always know the number of lines read. For example:

char **array_of_string (size_t *n)
{
    ...
    free (line);

    *n = index;  /* update n with index, so available in main() */

    return array;
}

您的下一个挑战是我如何检查,以确保我不读,并尝试存储比 5 行吗?那么,我该怎么办,如果我有比 5 线条更看?,那是什么?。这就是你要么从读取循环或更好,使用的realloc 功能重新分配阵列来增加可用的指针的数目。 (你可以添加你想要的很多,但一个标准的方法是的的目前一些指针你 - 这方法如下图所示)。

Your next challenge is "How do I check to make sure I don't read, and try to store, more than 5 lines?" Then, "What do I do if I have more than 5 lines to read?", "Then what?". That is where you either break from your read loop or, better, use the realloc function to reallocate array to increase the number of pointers available. (you can add as many as you want, but a standard approach is to double the current number of pointers you have -- that approach is shown below).

#define MAXLN 5
...
char **array_of_string (size_t *n)
{
    ...
    size_t maxln = MAXLN;
    ...
    while ((rd = getline(&line, &length, stdin)) != -1)
    {
        ...
        array[index++] = strdup(line); /* alloc & copy  */

        if (index == maxln) {   /* check limit reached  - reallocate */
            char **tmp = realloc (array, maxln * sizeof *array * 2);
            if (!tmp) {
                fprintf (stderr, "error: realloc - memory exhausted.\n");
                *n = index;
                return array;
            }
            array = tmp;  /* set new pointers to NULL */
            memset (array + maxln, 0, maxln * sizeof *array);
            maxln *= 2;
        }
    }
    ...
}

把所有的拼在一起,你可以不喜欢以下,最初分配一些合理预期的指针数抱着你希望阅读的行数。如果达到该限制你读完成之前,你只需的realloc 指针的 2 的电流的数量。 (您的realloc 使用 TMP 指针,以防止现有的所有数据的丢失在阵列如果的realloc 失败。如果的realloc 成功,您只要将阵列= TMP;

Putting all the pieces together, you could do something like the following, which initially allocate some reasonably anticipate number of pointers to hold the number of lines you expect to read. If you reach that limit before your read is done, you simply realloc the number of pointers to 2X current. (you realloc using a tmp pointer to protect against loss of all existing data in array if realloc fails. if realloc succeeds, you simply assign array = tmp;)

看看下面,让我知道,如果您有任何关于它的问题:

Take a look at the following and let me know if you have any questions about it:

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

#define MAXLN 5

char **array_of_string (size_t *n);

int main (void) {

    char **here = NULL;
    size_t i, lines = 0;

    /* assign array_of_string to here, check return */
    if (!(here = array_of_string (&lines))) {
        fprintf (stderr, "error: array_of_string return NULL.\n");
        return 1;
    }

    for (i = 0; i < lines; i++) /* print lines */
        printf (" line[%3zu] : %s\n", i, here[i]);

    for (i = 0; i < lines; i++) /* free lines */
        if (here[i]) free (here[i]);
    free (here);  /* free here */

    return 0;
}

char **array_of_string (size_t *n)
{
    char **array = NULL;
    char *line = NULL;
    size_t index = 0, length = 0, maxln = MAXLN;
    ssize_t rd = 0;

    if (!(array = calloc (MAXLN, sizeof *array))) {
        fprintf (stderr, "error: virtual memory exhausted.\n");
        return NULL;
    }

    while ((rd = getline(&line, &length, stdin)) != -1)
    {
        while (rd > 0 && (line[rd-1] == '\r' || line[rd-1] == '\n'))
            line[--rd] = 0; /* strip carriage return or newline   */

        array[index++] = strdup(line); /* alloc & copy  */

        if (index == maxln) {   /* check limit reached  - reallocate */
            char **tmp = realloc (array, maxln * sizeof *array * 2);
            if (!tmp) {
                fprintf (stderr, "error: realloc - memory exhausted.\n");
                *n = index;
                return array;
            }
            array = tmp;  /* set new pointers to NULL */
            memset (array + maxln, 0, maxln * sizeof *array);
            maxln *= 2;
        }
    }
    free(line);  /* free memory allocated by getline */

    *n = index;  /* update n with index, so available in main() */

    return array;
}

编译 - 启用警告

gcc -Wall -Wextra -o bin/stdintst stdintst.c

(或使用你的编译器类似的选项)

(or using similar options for your compiler)

输入文件

cat ../dat/damages.txt
Personal injury damage awards are unliquidated
and are not capable of certain measurement; thus, the
jury has broad discretion in assessing the amount of
damages in a personal injury case. Yet, at the same
time, a factual sufficiency review insures that the
evidence supports the jury's award; and, although
difficult, the law requires appellate courts to conduct
factual sufficiency reviews on damage awards in
personal injury cases. Thus, while a jury has latitude in
assessing intangible damages in personal injury cases,
a jury's damage award does not escape the scrutiny of
appellate review.

Because Texas law applies no physical manifestation
rule to restrict wrongful death recoveries, a
trial court in a death case is prudent when it chooses
to submit the issues of mental anguish and loss of
society and companionship. While there is a
presumption of mental anguish for the wrongful death
beneficiary, the Texas Supreme Court has not indicated
that reviewing courts should presume that the mental
anguish is sufficient to support a large award. Testimony
that proves the beneficiary suffered severe mental
anguish or severe grief should be a significant and
sometimes determining factor in a factual sufficiency
analysis of large non-pecuniary damage awards.

使用/输出

$ ./bin/stdintst <../dat/damages.txt
 line[  0] : Personal injury damage awards are unliquidated
 line[  1] : and are not capable of certain measurement; thus, the
 line[  2] : jury has broad discretion in assessing the amount of
 line[  3] : damages in a personal injury case. Yet, at the same
 line[  4] : time, a factual sufficiency review insures that the
 line[  5] : evidence supports the jury's award; and, although
 line[  6] : difficult, the law requires appellate courts to conduct
 line[  7] : factual sufficiency reviews on damage awards in
 line[  8] : personal injury cases. Thus, while a jury has latitude in
 line[  9] : assessing intangible damages in personal injury cases,
 line[ 10] : a jury's damage award does not escape the scrutiny of
 line[ 11] : appellate review.
 line[ 12] :
 line[ 13] : Because Texas law applies no physical manifestation
 line[ 14] : rule to restrict wrongful death recoveries, a
 line[ 15] : trial court in a death case is prudent when it chooses
 line[ 16] : to submit the issues of mental anguish and loss of
 line[ 17] : society and companionship. While there is a
 line[ 18] : presumption of mental anguish for the wrongful death
 line[ 19] : beneficiary, the Texas Supreme Court has not indicated
 line[ 20] : that reviewing courts should presume that the mental
 line[ 21] : anguish is sufficient to support a large award. Testimony
 line[ 22] : that proves the beneficiary suffered severe mental
 line[ 23] : anguish or severe grief should be a significant and
 line[ 24] : sometimes determining factor in a factual sufficiency
 line[ 25] : analysis of large non-pecuniary damage awards.

内存错误检查

在任何code你写,可动态分配的内存,您有任何关于分配的任何内存块2 responsibilites:(1)总是preserves指针的起始地址的内存块的话,(2 ),它可以当不再需要它被释放。

In any code your write that dynamically allocates memory, you have 2 responsibilites regarding any block of memory allocated: (1) always preserves a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed.

这是你必须使用一个内存错误检查程序,以确保你没有写超出/你分配的内存块外,试图在一个unintitialized值读取或碱跳,最后以确认您已释放所有您已分配的内存。

It is imperative that you use a memory error checking program to insure you haven't written beyond/outside your allocated block of memory, attempted to read or base a jump on an unintitialized value and finally to confirm that you have freed all the memory you have allocated.

有关Linux的的valgrind 是正常的选择。有许多微妙的方式滥用新的内存块。使用一个内存错误检查器,您可以识别任何问题并验证正确使用的内存你分配,而不是找出存在问题通过段错误。有每一个类似的平台内存检查。他们都是使用简单,只是通过它运行程序。

For Linux valgrind is the normal choice. There are many subtle ways to misuse a new block of memory. Using a memory error checker allows you to identify any problems and validate proper use of of the memory you allocate rather than finding out a problem exists through a segfault. There are similar memory checkers for every platform. They are all simple to use, just run your program through it.

$ valgrind ./bin/stdintst <../dat/damages.txt
==12233== Memcheck, a memory error detector
==12233== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==12233== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==12233== Command: ./bin/stdintst
==12233==
 line[  0] : Personal injury damage awards are unliquidated
 line[  1] : and are not capable of certain measurement; thus, the
<snip>
 line[ 24] : sometimes determining factor in a factual sufficiency
 line[ 25] : analysis of large non-pecuniary damage awards.
==12233==
==12233== HEAP SUMMARY:
==12233==     in use at exit: 0 bytes in 0 blocks
==12233==   total heap usage: 31 allocs, 31 frees, 1,989 bytes allocated
==12233==
==12233== All heap blocks were freed -- no leaks are possible
==12233==
==12233== For counts of detected and suppressed errors, rerun with: -v
==12233== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

一定要确认的所有堆块被释放 - 无泄漏可能的同样重要的错误摘要:从0 0上下文错误

让我知道如果您有任何进一步的问题。

Let me know if you have any further questions.

这篇关于返回从功能二维数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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