C++ 删除结构中的第一个元素
我有一个代码,试图删除结构中的第一个id。它过去是有效的,但现在它只是返回一个重复的俄语字母。我尝试重新安装VS,但没有帮助。我知道它是有效的,因为我在一个在线编译器上试用过它。 这两个警告也指向delete函数,我猜这就是问题所在。 警告C4156在不使用“delete”数组形式的情况下删除数组表达式;替换的数组形式 警告C4154删除数组表达式;提供了到指针的转换 以下是itslef的代码:C++ 删除结构中的第一个元素,c++,struct,delete-operator,C++,Struct,Delete Operator,我有一个代码,试图删除结构中的第一个id。它过去是有效的,但现在它只是返回一个重复的俄语字母。我尝试重新安装VS,但没有帮助。我知道它是有效的,因为我在一个在线编译器上试用过它。 这两个警告也指向delete函数,我猜这就是问题所在。 警告C4156在不使用“delete”数组形式的情况下删除数组表达式;替换的数组形式 警告C4154删除数组表达式;提供了到指针的转换 以下是itslef的代码: #include <stdio.h> #include <stdlib.h>
#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在任何代码中,无论我尝试什么,都会做同样的事情
另外,很抱歉格式不好,这是我们的教授需要的方式不要调用delete P->id。它除了使程序崩溃之外没有任何作用:它和它所在的结构都不是由new分配的
此外,切勿使用delete尝试释放malloced内存,或使用free释放新内存 是否要删除整个第一个节点?然后做一些类似的事情el_sp *oldp = p;
p = p->next;
free(oldp);
在中间删除一个节点实际上更容易一些。使用指向上一个元素prev和当前元素cur的跟踪指针。如果cur是要删除的节点,只需执行以下操作
prev->next->next = cur->next;
delete cur;
假设您使用新节点分配节点,您应该这样做 不要调用delete p->id。它除了使程序崩溃之外没有任何作用:它和它所在的结构都不是由new分配的
此外,切勿使用delete尝试释放malloced内存,或使用free释放新内存
是否要删除整个第一个节点?然后做一些类似的事情
el_sp *oldp = p;
p = p->next;
free(oldp);
在中间删除一个节点实际上更容易一些。使用指向上一个元素prev和当前元素cur的跟踪指针。如果cur是要删除的节点,只需执行以下操作
prev->next->next = cur->next;
delete cur;
假设您使用新节点分配节点,您应该这样做 我知道有时候教授们想按自己的方式做事,但知道什么是实现目标最直接的方式同样重要 这就是我想到的。请注意,没有手动内存管理,排序是自动的,您可以轻松地替换容器类型。在大多数情况下,向量是完全足够的——只有在基准测试表明您获得了更好的性能时,才应该使用该列表。在大多数情况下,你不会违背教授可能告诉你的:相信现实而不是教导
#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;
}
使用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;
}
我知道有时候教授们想按自己的方式做事,但知道什么是实现目标最直接的方式也同样重要 这就是我想到的。请注意,没有手动内存管理,排序是自动的,您可以轻松地替换容器类型。在大多数情况下,向量是完全足够的——只有在基准测试表明您获得了更好的性能时,才应该使用该列表。在大多数情况下,你不会违背教授可能告诉你的:相信现实而不是教导
#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;
}
使用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;
}
id是静态分配的数组。它不能被删除
delete p->id;
以上是错误的。删除内存未由新指针分配的指针会导致未定义的行为
你应该
delete p;
删除后,不应使用p。因此,pech_sp应该在前面而不是后面调用
pech_sp(p);
delete p;
id是静态分配的数组。它不能被删除
delete p->id;
以上是错误的。删除内存未由新指针分配的指针会导致未定义的行为
你应该
delete p;
删除后,不应使用p。因此,pech_sp应该在前面而不是后面调用
pech_sp(p);
delete p;
同时初始化变量,不要禁用错误检查。如果不这样做,您的应用程序将出现故障,因为您是用C++编程的:1在声明变量或指针时,不需要关键字struct。2喜欢使用新的动态内存;malloc不调用构造函数。3更倾向于使用STD::String,因为它为您管理动态内存,并且易于传递和复制。不要删除P-> ID。结构的ID字段没有动态分配。考虑通过引用传递指针。增加一个间接层次为更多的问题和缺陷打开了可能性。这是我们教授需要的方式-请注意,我们不是你的教授。您可以为我们重新格式化您的代码。事实上,这可能是值得赞赏的。同样,由于我们不是你的教授,你被允许/鼓励将你的代码简化为a。同时初始化你的变量,不要禁用错误检查。如果您不这样做,您的应用程序将出现故障,因为您是用C++编程的:1在声明变量o时,不需要关键字struct
r指针。2喜欢使用新的动态内存;malloc不调用构造函数。3更倾向于使用STD::String,因为它为您管理动态内存,并且易于传递和复制。不要删除P-> ID。结构的ID字段没有动态分配。考虑通过引用传递指针。增加一个间接层次为更多的问题和缺陷打开了可能性。这是我们教授需要的方式-请注意,我们不是你的教授。您可以为我们重新格式化您的代码。事实上,这可能是值得赞赏的。同样,由于我们不是你的教授,你被允许/鼓励将你的代码简化为a。谢谢,它可以工作,但我仍在试图弄清楚为什么它在我的电脑上不工作,但在在线编译器中工作。我怎么能删除中间的某个节点而不删除第一个节点?如果它看起来有效,那完全是偶然的。试图删除或释放未使用正确分配器分配的内存就是未定义行为的定义。至于删除中间,看到我的答案。谢谢,它的工作,但我仍然试图找出为什么它不工作在我的PC,但工作在一个在线编译器。我怎么能删除中间的某个节点而不删除第一个节点?如果它看起来有效,那完全是偶然的。试图删除或释放未使用正确分配器分配的内存就是未定义行为的定义。至于删除中间,请看我的答案。但是我需要用删除的节点输出列表,在删除之后如何调用它?@ DANIALI:什么意思是用删除的节点输出列表?但是我需要用删除的节点输出列表,如何在删除后不调用它的情况下执行此操作?@DaniAli您是什么意思?