Proszę o informację jak zadeklarować tablicę dynamiczną znając jej elementy.
deklaracja tablicy dynamicznej
- Rejestracja: dni
- Ostatnio: dni
- Postów: 52
- Rejestracja: dni
- Ostatnio: dni
- Postów: 1620
Używanie dynamicznych tablic (zamiast, na przykład, std::vector czy podobnych) to rozwiązanie sprzed półwiecza i proszenie się o kłopoty.
Tym niemniej, jeśli prowadzący ciśnie, albo ktoś Cię porwał i nie wypuści, dopóki tak nie zakodzisz, to można zdziałać coś takiego:
auto tablica = std::make_unique<TYP[]>(LICZBA_ELEMENTÓW);
(lub std::make_shared, w ramach potrzeb)
Gdzie, oczywiście, TYP to typ tych znanych elementów, a LICZBA_ELEMENTÓW to ich liczba.
A jak ktoś chce używać new[], to niech się sam męczy.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 52
Althorion napisał(a):
Używanie dynamicznych tablic (zamiast, na przykład,
std::vectorczy podobnych) to rozwiązanie sprzed półwiecza i proszenie się o kłopoty.Tym niemniej, jeśli prowadzący ciśnie, albo ktoś Cię porwał i nie wypuści, dopóki tak nie zakodzisz, to można zdziałać coś takiego:
auto tablica = std::make_unique<TYP[]>(LICZBA_ELEMENTÓW);(lub
std::make_shared, w ramach potrzeb)Gdzie, oczywiście,
TYPto typ tych znanych elementów, aLICZBA_ELEMENTÓWto ich liczba.
A jak ktoś chce używać
new[], to niech się sam męczy.
Althorion napisał(a):
Używanie dynamicznych tablic (zamiast, na przykład,
std::vectorczy podobnych) to rozwiązanie sprzed półwiecza i proszenie się o kłopoty.Tym niemniej, jeśli prowadzący ciśnie, albo ktoś Cię porwał i nie wypuści, dopóki tak nie zakodzisz, to można zdziałać coś takiego:
auto tablica = std::make_unique<TYP[]>(LICZBA_ELEMENTÓW);(lub
std::make_shared, w ramach potrzeb)Gdzie, oczywiście,
TYPto typ tych znanych elementów, aLICZBA_ELEMENTÓWto ich liczba.
A jak ktoś chce używać
new[], to niech się sam męczy.
Proste zadanko z pl.spoj.com. Próbuję zejść z czasu 0.01 za 'liczby pierwsze'.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 1620
To używaj std::vector jak człowiek współczesny, będzie grało. SPOJ nie wymaga nanooptymalizacji, a trudniej Ci będzie o błędy. Wyrabianie dobrych nawyków też się wtedy liczyć będzie na plus.
- Rejestracja: dni
- Ostatnio: dni
gaborek1987 napisał(a):
Proste zadanko z pl.spoj.com. Próbuję zejść z czasu 0.01 za 'liczby pierwsze'.
Lepiej pokaż swoje rozwiązanie.
Zadania na SPOJ mają to do siebie, że niektóre optymalizacje wymagają pomyślunku (lepszego algorytmu), a inne tylko optymalizacji operacji IO.
Standardowa optymalizacja IO (wywołać na początku `main):
void setupIO()
{
std::ios::synch_with_stdio(false);
std::cin.tie(nullptr);
}
Zastąpienie wszystkich std::endl przez '\n'.
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Poznań
- Postów: 540
Ja bym użył std::vector < Int > tablica;
- Rejestracja: dni
- Ostatnio: dni
Tu masz generator liczb pierwszy w czasie kompilacji:
https://wandbox.org/permlink/ODZ2TL4VgjJv6b0c
Jako, że widzę, że na SPOJ limit to 10000 to takie rozwiązanie jest najlepsze.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 2553
gaborek1987 napisał(a):
Proste zadanko z pl.spoj.com. Próbuję zejść z czasu 0.01 za 'liczby pierwsze'.
Pokaż kod. Może tracisz czas na niepotrzebne kopie, albo cin/cout zostawiłeś. Brak paru ampersandów może zmienić wszystko.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 52
Czitels napisał(a):
gaborek1987 napisał(a):
Proste zadanko z pl.spoj.com. Próbuję zejść z czasu 0.01 za 'liczby pierwsze'.
Pokaż kod. Może tracisz czas na niepotrzebne kopie, albo cin/cout zostawiłeś. Brak paru ampersandów może zmienić wszystko.
#include <iostream>
using namespace std;
bool all[10001];
struct prim {
int x;
prim* next;
};
struct lista {
prim* first;
prim* last;
void add(int y);
};
void lista::add(int y)
{
prim* a = new prim;
a->x = y;
prim* one = last;
(one->next) = a;
last = a;
}
int b, m;
int main()
{
// for(int i=1;i<10000;i++)all[i]=false;
lista* l = new lista;
prim* one = new prim;
one->x = 3;
l->first = one;
l->last = one;
all[2] = true;
all[3] = true;
prim* liczba;
for (int i = 5; i < 99; i += 2) {
b = 3;
liczba = (l->first);
while (b * b < i && i % b != 0) {
liczba = (liczba->next);
b = liczba->x;
}
if (b * b > i) {
l->add(i);
all[i] = true;
}
}
l->add(101);
all[101] = true;
for (int i = 103; i < 10000; i += 2) {
b = 3;
liczba = (l->first);
while (b * b < i && i % b != 0) {
liczba = (liczba->next);
b = liczba->x;
}
if (b * b > i)
all[i] = true;
}
int k, n;
scanf("%d", &m);
while (m > 0) {
m--;
scanf("%d", &b);
if (all[b])
printf("TAK\n");
else
printf("NIE\n");
}
}
- Rejestracja: dni
- Ostatnio: dni
Po co ci ta lista skoro masz już bool all[10001];?
Lecisz z sitem Eratostenesa, a potem sprawdzasz dane wejściowe w sicie.
Żadna lista nie jest potrzebna.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 52
Po co ci ta lista skoro masz już
bool all[10001];?
Lecisz z sitem Eratostenesa, a potem sprawdzasz dane wejściowe w sicie.
Żadna lista nie jest potrzebna.
To rozwiązanie z dnia: 2024-08-26
- Rejestracja: dni
- Ostatnio: dni
- Postów: 52
Wysłałem to w 2024-08-26 . Lista była niezbędna.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 2553
gaborek1987 napisał(a):
Wysłałem to w 2024-08-26 . Lista była niezbędna.
Po co niezbędna? Plus zauważyłem jedną rzecz. Nie pamiętam dokładnie sita, ale po co zaczynasz od b=3 i wykonujesz operacje od nowa? Nie możesz bazować na poprzednich?
b = 3;
liczba = (l->first);
while (b * b < i && i % b != 0) {
liczba = (liczba->next);
b = liczba->x;
}
- Rejestracja: dni
- Ostatnio: dni
- Postów: 683
a nie łatwiej tak;
int total=100;
char *data=new char[total];;
a po wykorzystaniu zmiennej żeby zwolnić bufor to:
delete data;
jeśli elementy mają być jedno bajtowe a dla int
int *data=new int[total];;
i float:
float *data=new float[total];
elementy są 4 bajtowe
- Rejestracja: dni
- Ostatnio: dni
wilkwielki napisał(a):
a nie łatwiej tak;
NIE.
Chyba, że cofniesz się do lat '90.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 1107
wilkwielki napisał(a):
a nie łatwiej tak;
int total=100; char *data=new char[total];;a po wykorzystaniu zmiennej żeby zwolnić bufor to:
delete data;
Jak już odpowiadasz na pytanie, to przynajmniej nie wprowadzaj w błąd. Nie tak się zwalnia pamięć przydzielaną w ten sposób.
Tworzysz za pomocą new [] to zwalniasz za pomocą delete []
- Rejestracja: dni
- Ostatnio: dni
- Postów: 683
przecież operator new i delete jest znany od wieków i działa do dzisiaj, sam tak wykorzystuje bufforowanie danych
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Kraków
- Postów: 32
wilkwielki napisał(a):
przecież operator new i delete jest znany od wieków i działa do dzisiaj, sam tak wykorzystuje bufforowanie danych
tak samo jak lampa naftowa. Mimo to ludzie używają żarówek (jeżeli mają prąd). Poza tym ignorujesz komentarz Mr.YaHooo.
Dwa przykłady:
https://godbolt.org/z/aPxbd43xY
#include <iostream>
class Test {
public:
Test() { std::cout << "Konstruktor\n"; }
~Test() { std::cout << "Destruktor\n"; }
};
int main() {
Test* ptr = new Test[3]; // Alokujemy tablicę 3 obiektów
delete ptr; // ❌ BŁĄD! Powinno być delete[]
return 0;
}
Z odpowiednimi flagami się nawet nie skompiluje. Bez flag po prostu nie działa (SIGSEGV). Najprawdopodobniej wywołało by destruktor tylko dla pierwszego elementu. Wyciek i/lub niedozwolony dostęp do pamięci.
https://godbolt.org/z/xYsMT1Tc3
#include <iostream>
int main() {
int* arr = new int[5]; // Alokujemy tablicę
delete arr; // ❌ UB – powinno być delete[]
return 0;
}
Tu jak wyżej. Z odpowiednimi flagami się nawet nie skompiluje. Bez flag wygląda że działa ale to nie znaczy że jest dobrze. To bardziej przypadek, a nie gwarancja. Wyciek i/lub niedozwolony dostęp do pamięci i tak być może. Poza tym to chyba niezdefiniowane zachowanie.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 683
z mojej strony to jest tak ze zawsze wywołuje samo delete i zwalnia buffor starczy wrzucić w petle new i delete i nie bedzie przeciązenia stosu , cały mój framework bazuje na samym operatorze delete i działa niezawodnie pierwsze raz słyszę że trzeba podawać po delete klamry, to nawet jeśli to było by tak ze po delete daje się klamrę to na jakiej wersji c++ działacie , ja korzystam z vc++6.0 Pro z c++98 i wszystko hula dobrze, dla mnie to dziwne
- Rejestracja: dni
- Ostatnio: dni
- Postów: 1007
https://isocpp.org/wiki/faq/freestore-mgmt#delete-array-built-ins
Can I drop the [] when deleteing an array of some built-in type (char, int, etc)?
No!
Sometimes programmers think that the
[]in thedelete[]p only exists so the compiler will call the appropriate destructors for all elements in the array. Because of this reasoning, they assume that an array of some built-in type such as char or int can be deleted without the[]. E.g., they assume the following is valid code:void userCode(int n) { char* p = new char[n]; // ... delete p; // ← ERROR! Should be delete[] p ! }But the above code is wrong, and it can cause a disaster at runtime. In particular, the code that’s called for
delete pisoperator delete(void*), but the code that’s called fordelete[] pisoperator delete[](void*). The default behavior for the latter is to call the former, but users are allowed to replace the latter with a different behavior (in which case they would normally also replace the correspondingnewcode inoperator new[](size_t)). If they replaced thedelete[]code so it wasn’t compatible with the delete code, and you called the wrong one (i.e., if you saiddelete prather thandelete[] p), you could end up with a disaster at runtime.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 683
z tego co widze to są po prostu różnice kodo zmianowe, diabeł tkwi w wersjach c++ i tyle po prostu z mojej stony
- Rejestracja: dni
- Ostatnio: dni
- Postów: 1107
wilkwielki napisał(a):
z mojej strony to jest tak ze zawsze wywołuje samo delete i zwalnia buffor starczy wrzucić w petle new i delete i nie bedzie przeciązenia stosu , cały mój framework bazuje na samym operatorze delete i działa niezawodnie pierwsze raz słyszę że trzeba podawać po delete klamry, to nawet jeśli to było by tak ze po delete daje się klamrę to na jakiej wersji c++ działacie , ja korzystam z vc++6.0 Pro z c++98 i wszystko hula dobrze, dla mnie to dziwne
A dla mnie jest dziwne, bo w każdej książce z jaką miałem do czynienia odnośnie C++ pisali, że pamięć zaalokowaną przez new zwalniamy przez delete. Natomiast new[] implikuje późniejsze użycie delete[].
Ale ok, możesz mi nie wierzyć. Skoro wyciągasz ciężkie działo w postaci standardu C++, więc szukamy.
https://en.cppreference.com/w/cpp/links
Masz tam sekcję C++ standard documents and drafts
Następnie używam linka: N1146 (PDF) - C++98 final working draft.
Znajduję się tu: https://open-std.org/JTC1/SC22/WG21/docs/wp/pdf/nov97-2/
Dalej idę tu: https://open-std.org/JTC1/SC22/WG21/docs/wp/pdf/nov97-2/body.pdf
Przeglądam PDF'a i mam całą sekcję poświęconą operatorowi delete. Na samym początku pisze jak wół:
5.3.5 Delete
1 The delete-expression operator destroys a most derived object (1.7) or array created by a new-expression.
delete-expression:
::opt delete cast-expression
::opt delete [ ] cast-expression
The first alternative is for non-array objects, and the second is for arrays. The operand shall have a pointer type, or a class type having a single conversion function (12.3.2) to a pointer type. The result has type void
Więc jak widzisz cały Twój framework który bazuje na samym operatorze delete jest wbrew standardowi. To, że działa to po prostu szczęście. Po prostu pamięć Ci ucieka, a Ty nawet tego nie sprawdzałeś. Więc nie są to żadne różnice "kodo zmianowe" (w ogóle co to oznacza?) a zwykłe szczęście.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 1007
To macie jeszcze screenshoot z książki Stroustrupa "Projektowanie i rozwój języka C++"

Wersja C++ 2.0 to według wiki 1989 rok, 9 lat nim powstał pierwszy standard.
- Rejestracja: dni
- Ostatnio: dni
a wy nie rozmawiacie z alter ego tego innego gościa od visual c++ 6 z roku 2002? bo jak patrzę to dwa konta pisza o tym samym ale modzi by musieli sprawdzić czy to nie ten sam ip.