Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 第一次尝试使用new动态创建结构数组时,程序挂起,没有错误_C++_Arrays_Dynamic_Struct_New Operator - Fatal编程技术网

C++ 第一次尝试使用new动态创建结构数组时,程序挂起,没有错误

C++ 第一次尝试使用new动态创建结构数组时,程序挂起,没有错误,c++,arrays,dynamic,struct,new-operator,C++,Arrays,Dynamic,Struct,New Operator,我正试图解决如何为作业创建动态数组的问题,但无论我做什么,在输入3个或更多条目后,我的程序都会继续挂起 我没有收到任何错误,必须手动关闭控制台窗口,但没有任何方向,我不确定我到底做错了什么 无论我在控制台中创建3+结构时做了什么更改,我的程序都会在输入“n”以结束新事件的创建后挂起 int readEvents(Event* ev_ptr[], int size) { char answer = 'y', slash; int i = 0; cout <<

我正试图解决如何为作业创建动态数组的问题,但无论我做什么,在输入3个或更多条目后,我的程序都会继续挂起

我没有收到任何错误,必须手动关闭控制台窗口,但没有任何方向,我不确定我到底做错了什么

无论我在控制台中创建3+结构时做了什么更改,我的程序都会在输入“n”以结束新事件的创建后挂起

int readEvents(Event* ev_ptr[], int size)
{
    char answer = 'y', slash;
    int i = 0;

    cout << "\nCreate an event [y/n]? ";
    cin >> answer;
    cin.ignore();
    while (answer == 'y' || answer == 'Y')
    {
        ev_ptr[i] = new Event;

        cout << "\nEnter description: ";
        cin.getline(ev_ptr[i]->desc, 80, '\n');

        cout << "\nEnter date: ";
        cin >> ev_ptr[i]->date.month >> slash >> ev_ptr[i]->date.day >> slash >> ev_ptr[i]->date.year;
        cin.ignore();

        cout << "\nEnter time: ";
        cin >> ev_ptr[i]->time.hour >> slash >> ev_ptr[i]->time.minute;
        cin.ignore();

        i++;

        cout << "\nCreate an event [y/n]? ";
        cin >> answer;
        cin.ignore();
    }

    return i;
}
int-readEvents(事件*ev_ptr[],int-size)
{
字符答案='y',斜杠;
int i=0;
回答;
cin.ignore();
while(答案=='y'|答案=='y')
{
ev_ptr[i]=新事件;
cout desc,80,“\n”);
cout>ev_ptr[i]->date.month>>斜线>>ev_ptr[i]->date.day>>斜线>>ev_ptr[i]->date.year;
cin.ignore();
cout>ev_ptr[i]->time.hour>>斜线>>ev_ptr[i]->time.min;
cin.ignore();
i++;
回答;
cin.ignore();
}
返回i;
}
任何帮助都将不胜感激

编辑:

以下是我声明ev_ptr阵列大小的主要函数:

int main()
{
    Event* event_pointers[100];
    int count = readEvents(event_pointers, 100), userMonth;
    char userString[80];

    cout << "\nEnter a search string: ";
    cin.getline(userString, 80, '\n');
    cin.ignore();

    linsearch(event_pointers, count, userString);

    cout << "\nEnter a month to list Events for: ";
    cin >> userMonth;
    cin.ignore();

    binsearch(event_pointers, count, userMonth);

    for (int j = 0; j < count; j++) //Cleanup loop
        delete event_pointers[j];

    cout << "\nPress any key to continue...";
    (void)_getch();
    return 0;
}
intmain()
{
事件*事件指针[100];
int count=readEvents(事件指针,100),userMonth;
char userString[80];
每月一次;
cin.ignore();
binsearch(事件指针、计数、用户月);
对于(int j=0;j为什么不使用
std::vector
std::unique

#include <vector>
#include <memory>

class Event { }

int main()
{
  std::vector<std::unique_ptr<Event>> events;
  readEvents(events);
}

int readEvents(std::vector<std::unique_ptr<Event>>& events, int size)
{
  ...
  while (answer == 'y' || answer == 'Y')
  {
    ev_ptr[i] = std::make_unique<Event>();
    ...
  }
}
#包括
#包括
类事件{}
int main()
{
向量事件;
readEvents(事件);
}
int readEvents(std::vector&events,int size)
{
...
while(答案=='y'|答案=='y')
{
ev_ptr[i]=std::make_unique();
...
}
}

使用
new
delete
是一种古老的做事方式。作为一种古老的做事方式,有几十年的代码可以利用它。正如我在上面的评论中总结的那样,您目前声明
100个
指针来键入
事件
,然后使用
new
来分配存储空间每个单独的
struct Event
实例。通过使用一个固定的指针数组——您将被锁定,不再有最初为其声明指针的事件。这是一种非常不灵活的方法

相反,只需声明一个内存块来保存一些初始数量的事件,并为分配的元素数和填充的元素数保留一对计数器。当
filled==allocated
时,只需分配另一个内存块(比如保存两倍于当前元素数的元素),然后将数据从原始块复制到新块,删除原始块,并根据需要重复多次。(您基本上是使用
new/delete
执行手动
realloc()

下面是一个简短的示例。在这个示例中,我使用了一个简化的
事件
结构。(您可以处理进一步将日期和时间拆分为yyyy-mm-dd和H:M:S)。该示例首先分配2个
事件实例
,然后继续读取用户的输入,更新分配大小,并根据需要将原始文件复制为新文件。初始设置和重新分配代码如下:

#include <iostream>
#include <cstring>

#define MAXDESC  80    /* max description length */
#define MAXDTTM  32    /* max date/time lengths */
#define EVSIZE    2    /* initial number of Event elements allocated */

struct Event {
    char desc[MAXDESC];
    char date[MAXDTTM];
    char time[MAXDTTM];
};

/** reallocate e to twice 'size' elements */
Event *reallocEVx2 (Event *e, size_t *size)
{
    Event *tmp = new Event[*size * 2];      /* allocate new block 2x in size */

    std::memcpy (tmp, e, *size * sizeof *e);    /* copy old to new */
    delete[] e;                                 /* delete old */
    *size *= 2;                                 /* update allocated size */

    return tmp;     /* return pointer to new block */
}
main()
中,您只需声明计数器,以跟踪分配的元素数(
size
如下)和使用的元素数(
nelem
如下),并为
事件的初始两个实例进行分配,然后开始读取数据。代码通过输出内存统计信息来完成(分配的元素/使用的元素)并输出每个存储的
事件
实例,例如

int main (void) {

    size_t nelem = 0;
    size_t size = EVSIZE;
    Event *events = new Event[size];    /* allocate initial 'size' elements */

    if (!readEvents (&events, &nelem, &size)) {     /* read/fill events */
        std::cerr << "error: no events read.\n";
        return 1;
    }

    /* output memory useage (elements allocated/filled) */
    std::cout << "\nelements allocated: " << size <<
                 "\nelements filled   : " << nelem << "\n\n"; 

    for (size_t i = 0; i < nelem; i++)  /* output all events */
        std::cout << events[i].desc << "    " << events[i].date << "    " <<
                    events[i].time << '\n';

    delete[] events;    /* free memory  */
}

查看一下,如果你对这个方法有进一步的疑问,请告诉我。< /P>你把数组作为EvpPTR参数传递给我们的是什么?请告诉我们调用代码< >代码> ReaveOs/Cuth>的代码:为什么在分配元素时不检查数组大小?在现代C++中,几乎没有一个好主意。直接使用

new
。使用
std::vector
而不是直接包含
事件的数组,而不是指针。如果出于某种原因确实需要指针,则使用
std::shared_ptr
std::unique_ptr
。@sklott分配经常要求直接使用
new
。I如果只看一个函数,就很难判断问题出在哪里。请发布一个。这不能回答OP的问题,所以应该是一个注释,而不是答案。很遗憾,我不允许在这个任务中使用向量。非常感谢你花这么多时间,这真的帮助我更好地理解事情!很高兴它有帮助。就像任何事情一样,se把所有的部分放在一起真的有助于它们就位。祝你编码顺利!你可以通过使用模板使realloc函数成为通用函数——但请另存一天。只需知道你可以编写一个通用的重新分配函数,这样你就不必为每种不同的类型编写一个。正如我上面所评论的,基本上这就是“改造”了
std::vector
,因此,当你不需要自己实现所有事情时,最好直接使用它。(我无法理解为什么在我们这个教育水平的时代存在这样的任务,我的意思是,在尝试实现它之前,你不应该学习如何使用
std::vector吗?)
int main (void) {

    size_t nelem = 0;
    size_t size = EVSIZE;
    Event *events = new Event[size];    /* allocate initial 'size' elements */

    if (!readEvents (&events, &nelem, &size)) {     /* read/fill events */
        std::cerr << "error: no events read.\n";
        return 1;
    }

    /* output memory useage (elements allocated/filled) */
    std::cout << "\nelements allocated: " << size <<
                 "\nelements filled   : " << nelem << "\n\n"; 

    for (size_t i = 0; i < nelem; i++)  /* output all events */
        std::cout << events[i].desc << "    " << events[i].date << "    " <<
                    events[i].time << '\n';

    delete[] events;    /* free memory  */
}
#include <iostream>
#include <cstring>

#define MAXDESC  80    /* max description length */
#define MAXDTTM  32    /* max date/time lengths */
#define EVSIZE    2    /* initial number of Event elements allocated */

struct Event {
    char desc[MAXDESC];
    char date[MAXDTTM];
    char time[MAXDTTM];
};

/** reallocate e to twice 'size' elements */
Event *reallocEVx2 (Event *e, size_t *size)
{
    Event *tmp = new Event[*size * 2];      /* allocate new block 2x in size */

    std::memcpy (tmp, e, *size * sizeof *e);    /* copy old to new */
    delete[] e;                                 /* delete old */
    *size *= 2;                                 /* update allocated size */

    return tmp;     /* return pointer to new block */
}

/** read events from user reallocating as required
 *  (note: must pass address-of-pointer, not just pointer)
 */
size_t readEvents (Event **e, size_t *nelem, size_t *size)
{
    char buf[MAXDESC];

    for (;;) {  /* loop continually until something other than 'y' entered */
        std::cout << "\nCreate event (y/n)? ";
        if (!std::cin.getline (buf, sizeof buf) || *buf != 'y')
            break;

        if (*nelem == *size)    /* check if realloc needed */
            *e = reallocEVx2 (*e, size);

        /* get input */
        std::cout << "  Enter description: ";
        if (!std::cin.getline ((*e)[*nelem].desc, MAXDESC))
            break;

        std::cout << "  Enter date: ";
        if (!std::cin.getline ((*e)[*nelem].date, MAXDTTM))
            break;
        /* create stringstream to parse date into yyyy-mm-dd here */

        std::cout << "  Enter time: ";
        if (!std::cin.getline ((*e)[*nelem].time, MAXDTTM))
            break;
        /* create stringstream to parse time into H:M:S here */

        (*nelem)++;     /* update no. of elements filled */
    }

    return *nelem;      /* return no. of elements filled */
}

int main (void) {

    size_t nelem = 0;
    size_t size = EVSIZE;
    Event *events = new Event[size];    /* allocate initial 'size' elements */

    if (!readEvents (&events, &nelem, &size)) {     /* read/fill events */
        std::cerr << "error: no events read.\n";
        return 1;
    }

    /* output memory useage (elements allocated/filled) */
    std::cout << "\nelements allocated: " << size <<
                 "\nelements filled   : " << nelem << "\n\n"; 

    for (size_t i = 0; i < nelem; i++)  /* output all events */
        std::cout << events[i].desc << "    " << events[i].date << "    " <<
                    events[i].time << '\n';

    delete[] events;    /* free memory  */
}
$ ./bin/events_new-del

Create event (y/n)? y
  Enter description: Event 1
  Enter date: 11/29/19
  Enter time: 12:30:31

Create event (y/n)? y
  Enter description: Event 2
  Enter date: 11/29/19
  Enter time: 12:30:41

Create event (y/n)? y
  Enter description: Event 3
  Enter date: 11/29/19
  Enter time: 12:30:51

Create event (y/n)? y
  Enter description: Event 4
  Enter date: 11/29/19
  Enter time: 12:31:01

Create event (y/n)? y
  Enter description: Event 5
  Enter date: 11/29/19
  Enter time: 12:31:11

Create event (y/n)? n

elements allocated: 8
elements filled   : 5

Event 1    11/29/19    12:30:31
Event 2    11/29/19    12:30:41
Event 3    11/29/19    12:30:51
Event 4    11/29/19    12:31:01
Event 5    11/29/19    12:31:11