我有一个代码想要删除结构中的第一个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.很抱歉格式不好,这是我们教授需要的格式
答案 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;