获取指定索引之间的数组的子数组

Posted

技术标签:

【中文标题】获取指定索引之间的数组的子数组【英文标题】:Get subarray of an array between specified indexes 【发布时间】:2020-09-11 02:53:19 【问题描述】:

我对 C 语言比较陌生。 在我的程序中,我有一个结构数组,它会定期附加。

我想编写一个函数,它允许我将结构从索引返回到此数组中的另一个:

struct Log
    int sensorState;
    int speed;
;

struct Log myEvent[10000];

这是我所做的,但它不起作用(SIGSEV 被抛出):

struct Log *getEvents(int from, int to)
    struct Log *events[to-from+1];

    for(int i=0; i<=to-from;i++)
        events[i]->speed = myEvent[i].speed;
        events[i]->sensorState = myEvent[i].sensorState;
    
    return events 
 

感觉在 Java 或 Python 中会很容易......但我无法在 C 中做到这一点,我尝试了很多东西,我就在这里。

【问题讨论】:

首先该函数不返回任何内容。其次,变量events 是一个local 变量,其生命周期在函数返回时结束。从函数返回时,指向该数组的任何指针都会立即失效。 我还建议你对那个复制循环做一些rubber duck debugging。你真正在复制什么? 你在struct Log myEvent[10000]中也少了一个分号 哦,你取消引用循环内的 uninitialized 指针。你永远不会让events 数组的指针实际上指向某个地方。所以最多三个案例undefined behavior 这能回答你的问题吗? Getting a sub-array from an existing array 【参考方案1】:

呈现的代码有几个问题,其中:

你的函数声明它返回一个struct Log *,但它实际上并没有返回任何东西。 我想这个想法是该函数将返回events,但它会衰减为struct Log **,而您需要一个struct Log *。 此外,返回events 没有用处,因为该数组具有自动存储持续时间。也就是说,它的生命周期在创建它的块执行结束时结束。在这种情况下,从函数接收到的指针将是无效的。 您正在取消引用 events 的(指针)元素,而没有将它们设置为指向任何对象。

你可以做两件主要的事情:

    返回指向文件范围myEvent 数组的适当元素的指针。这将避免任何分配或复制任何东西的需要,但这是一把双刃剑。然后,您将通过 myEvent 和返回的指针上的不同索引访问相同的 struct Log 对象,这可能是您想要实现的目标,也可能不是。但是,在这种情况下,一个函数是多余的,因为你所需要的只是

    struct Log *someEvents = myEvent + from;
    

    或者,让您的函数为所需数量的struct Log 对象副本动态分配空间,从myEvent 复制所需数据,并返回指向分配空间的指针。在这种情况下,对于 struct Log 结构的特定内容,使用 memcpy() 进行复制会更清晰、更有效:

    struct Log *getEvents(int from, int to)
        size_t size = (to - from + 1) * sizeof(struct Log);
        struct Log *events = malloc(size);
    
        if (events) 
            memcpy(events, myEvent + from, size);
         // else malloc failed and 'events' is null
    
        return events;
     
    

动态分配的空间一直存在,直到您使用free() 显式取消分配它。 (在丢失指向已分配空间的指针之前,您最终必须这样做,否则您会发生内存泄漏。)

【讨论】:

你错了,@Paazik。返回的指针指向to - from + 1 项的第一个 项。您可以将其索引到(使用从零开始的索引)以访问这些元素中的任何一个。等效地,您可以使用指针算法来获取指向其他对象的指针。【参考方案2】:

Log *myEventLog *events 以及索引传递给函数。

typedef struct Log
        int sensorState;
        int speed;
    Log;


    void getEvents(Log *myEvent,Log *events,int from, int to)

        for(int i=from; i<to-from+1;i++)
            events[i].speed = myEvent[i].speed;
            events[i].sensorState = myEvent[i].sensorState;
        
     

【讨论】:

以上是关于获取指定索引之间的数组的子数组的主要内容,如果未能解决你的问题,请参考以下文章

需要在特定索引处重叠数组的子数组

数组560. 和为K的子数组

怎么用java取出出指定条件二维数组的子数组

从嵌套列表的子数组返回元素的索引

获取具有特定键/值对的二维数组中的子数组

2021-07-16:三个无重叠子数组的最大和。给定数组 nums 由正整数组成,找到三个互不重叠的子数组的最大和。每个子数组的长度为k,我们要使这3*k个项的和最大化。返回每个区间起始索引的列表(索