You need to consider several things.
1.) the case of an empty list
if(head == nullptr){//Empty list case
return nullptr;
}
2.) The target to be removed is the head node and this is the only node in the list.
if (head == target && target->p_next == head){
create a temp node with the data value of target
target = nullptr;//Since nothing points to target now it is for all intents and purposes deleted from the list but the data is still there so you can do something with it. I assume this is necessary because you return a node *.
return the temp node
}
3.) Create a loop that iterates through the entire list. You have something that would only delete the next node which works if you have a two item list and target was the second item.
auto next_pointer = head->p_next;//could not be target->p_next as this assumed
while (next_pointer->p_next != target){//This while loop traverses the list rather than just deleting the next entry.
4.)Inside you loop add a check to see if the list has been traversed and target was never found.
if (next_pointer->p_next == head){
return nullptr;
}//end IF
5.) Inside the loop add the else case which means target was in an arbitrary location in the list. Since I gave you the rest I'll leave you to get this part. It's not hard just a few lines longer than the statements above.