删除结构中的第一个元素

时间:2020-06-16 22:56:11

标签: c++ struct delete-operator

我有一个代码想要删除结构中的第一个ID。它曾经可以工作,但是现在只返回“ЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭ”(重复的俄语字母)。我尝试重新安装VS,但没有帮助。我知道它有效,因为我在在线编译器上尝试过它。 这两个警告也指向删除功能,我猜这是问题所在。 警告C4156删除数组表达式而不使用“ delete”的数组形式;数组形式替换
警告C4154删除数组表达式;转换为提供的指针

这是它的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <locale.h>
#include <iostream>
#pragma warning (disable: 4703) //disables warning of uninitialized variable j
using namespace std;
#define  MAXDL    9      
struct el_sp
{
    char  id[MAXDL];
    struct el_sp* sled;
};
void  vkl(struct el_sp** p, char t_id[]) //enters the entered ID's from keyboard into the struct
{
    struct el_sp* pt,
        * k, * j;
    pt = (struct el_sp*)malloc(sizeof(struct el_sp));
    strcpy_s(pt->id, t_id);
    if (*p == NULL || strcmp(pt->id, (*p)->id) < 0)
    {
        pt->sled = *p; *p = pt;
    }
    else
    {
        k = *p;
        while (k != NULL && strcmp(pt->id, k->id) >= 0)
        {
            j = k; k = k->sled;
        }
        j->sled = pt; pt->sled = k;
    }
}

void pech_sp(struct el_sp* p) //prints the struct
{
    struct el_sp* i;
    char* o;
    printf("\Result:\n");
    for (i = p; i != NULL; i = i->sled)
        puts(i->id);
}

int main() {
    setlocale(LC_ALL, "RUS");
    struct el_sp* p;
    unsigned  n;
    unsigned  i;
    char t_id[MAXDL];

    printf("\nEnter the amount of identificators\n n=");
    scanf_s("%u", &n);
    getchar();
    p = NULL;
    printf("Enter the identificators (press enter after each one)\n");
    for (i = 1; i <= n; i++)
    {
        gets_s(t_id);
        vkl(&p, t_id);
    }
    delete p->id;
    pech_sp(p);
    return 0;
}

P.S。无论我用什么代码,Delete都会做同样的事情 P.S.S.很抱歉格式不好,这是我们教授需要的格式

3 个答案:

答案 0 :(得分:3)

请勿致电delete p->id。除了崩溃程序之外,它没有任何用途:new都没有分配它或它所在的结构。

也不要使用delete来释放malloc版的内存,也不要使用free来释放new版的内存。

您要删除整个第一个节点吗?然后做类似的事情

el_sp *oldp = p;
p = p->next;
free(oldp);

实际上,删除中间的节点要容易一些。使用指向前一个元素(prev)和当前元素(cur)的“跟踪指针”。如果cur是您要删除的节点,只需执行

prev->next->next = cur->next;
delete cur;

(假设您应该用new分配节点!)

答案 1 :(得分:1)

我知道有时候教授会按自己的方式做事,但是了解什么是实现目标最直接的方法同样重要。

这就是我想出的。请注意,没有手动内存管理,排序是自动的,您可以轻松替换容器类型。在大多数情况下,向量将是完全足够的-仅当基准测试表明您可以获得更好的性能时,才应使用此列表。在大多数情况下,您不会(与教授可能告诉您的相反:信任现实而不是教))。

#include <algorithm>
#include <clocale>
#include <iostream>
#include <list>
#include <vector>

struct El_Sp
{
    std::string id;
};

#if 1
using El_Spy = std::vector<El_Sp>;
#else
using El_Spy = std::list<El_Sp>;
#endif

template <> struct std::less<El_Sp>
{
    bool operator()(const El_Sp &l, const El_Sp &r) const
    { return l.id < r.id; }
};

std::istream &operator>>(std::istream &in, El_Sp &el_sp)
{
    return in >> el_sp.id;
}

std::ostream &operator<<(std::ostream &out, const El_Sp &el_sp)
{
    return out << el_sp.id;
}

std::ostream &operator<<(std::ostream &out, const El_Spy &el_spy)
{
    for (auto &el : el_spy)
        out << el << '\n';
    return out;
}

template <typename Container, typename T, typename Pred = std::less<typename Container::value_type>>
auto insert_sorted(Container &cont, T &&item, Pred pred = {})
{
    return cont.insert(
        std::upper_bound(std::begin(cont), std::end(cont), std::as_const(item), pred),
           std::forward<T>(item));
}

void enter_id(El_Spy &el_spy)
{
    El_Sp el;
    std::cin >> el;
    insert_sorted(el_spy, el);
}

int main()
{
    El_Spy el_spy;

    std::setlocale(0, "");
    size_t n = 0;
    std::cout << "Введите количество идентификаторов n=";
    std::cin >> n;
    std::cout << "Введите идентификаторы. Нажмите Enter после каждого.\n";
    while (n--)
        enter_id(el_spy);

    std::cout << "Идентификаторы:\n" << el_spy;
}

示例会话:

Введите количество идентификаторов n=3                                                                                                          
Введите идентификаторы. Нажмите Enter после каждого.                                                                                            
Алла                                                                                                                                            
Дарья                                                                                                                                           
Вера                                                                                                                                            
Идентификаторы:                                                                                                                                 
Алла                                                                                                                                            
Вера                                                                                                                                            
Дарья                                                                                                                                           

使用std::vector时,插入排序并不是真正必要-输入所有标识符后,您可以使用std::sort

int main()
{
    std::setlocale(0, "");
    size_t n = 0;
    std::cout << "Введите количество идентификаторов n=";
    std::cin >> n;

    El_Spy el_spy(n);
    std::cout << "Введите идентификаторы. Нажмите Enter после каждого.\n";
    for (auto &el_sp : el_spy)
        std::cin >> el_sp;

    std::sort(std::begin(el_spy), std::end(el_spy), std::less<El_Sp>());

    std::cout << "Идентификаторы:\n" << el_spy;
}

答案 2 :(得分:1)

struct el_sp
{
   char  id[MAXDL];
   struct el_sp* sled;
};

id是静态分配的数组。无法删除。

  delete p->id;

以上是错误的。删除未由new分配内存的指针会导致未定义的行为。

您应该拥有

  delete p;

删除后,您不应使用p。因此,pech_sp应该在调用之前而不是之后调用。

pech_sp(p);
delete p;